@leofcoin/chain 1.9.13 → 1.9.14
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.
- package/exports/browser/chain.js +66 -70
- package/exports/chain.js +66 -70
- package/package.json +1 -1
package/exports/browser/chain.js
CHANGED
|
@@ -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(
|
|
6120
|
-
if (!this.#peerReputations.has(
|
|
6121
|
-
this.#peerReputations.set(
|
|
6119
|
+
async #recordPeerFailure(peerId, reason) {
|
|
6120
|
+
if (!this.#peerReputations.has(peerId)) {
|
|
6121
|
+
this.#peerReputations.set(peerId, { score: 0, failures: [] });
|
|
6122
6122
|
}
|
|
6123
|
-
const rep = this.#peerReputations.get(
|
|
6123
|
+
const rep = this.#peerReputations.get(peerId);
|
|
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 ${
|
|
6130
|
+
console.warn(`[peer-ban] Peer ${peerId} banned after ${rep.failures.length} failures`);
|
|
6131
6131
|
try {
|
|
6132
|
-
await globalThis.peernet.disconnect(
|
|
6132
|
+
await globalThis.peernet.disconnect(peerId);
|
|
6133
6133
|
} catch (e) {
|
|
6134
|
-
debug(`Failed to disconnect peer ${
|
|
6134
|
+
debug(`Failed to disconnect peer ${peerId}`);
|
|
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 (
|
|
6255
|
-
console.error(
|
|
6254
|
+
} catch (error) {
|
|
6255
|
+
console.error(error);
|
|
6256
6256
|
}
|
|
6257
6257
|
const end = Date.now();
|
|
6258
6258
|
console.log((end - start) / 1e3 + " s");
|
|
@@ -6367,10 +6367,10 @@ 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 (
|
|
6371
|
-
const
|
|
6372
|
-
debug(`peernet request failed: ${request} -> ${
|
|
6373
|
-
throw
|
|
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;
|
|
6374
6374
|
}
|
|
6375
6375
|
}
|
|
6376
6376
|
async #decodeKnownBlocksResponse(response) {
|
|
@@ -6434,8 +6434,8 @@ class Chain extends VersionControl {
|
|
|
6434
6434
|
let txData;
|
|
6435
6435
|
try {
|
|
6436
6436
|
txData = await globalThis.peernet.get(key, "transaction");
|
|
6437
|
-
} catch (
|
|
6438
|
-
debug(`Failed to get transaction ${key}:`,
|
|
6437
|
+
} catch (error) {
|
|
6438
|
+
debug(`Failed to get transaction ${key}:`, error?.message ?? error);
|
|
6439
6439
|
}
|
|
6440
6440
|
if (txData !== void 0) {
|
|
6441
6441
|
transactionsToGet.push(transactionPoolStore.put(key, txData));
|
|
@@ -6444,11 +6444,11 @@ class Chain extends VersionControl {
|
|
|
6444
6444
|
}
|
|
6445
6445
|
return Promise.all(transactionsToGet);
|
|
6446
6446
|
}
|
|
6447
|
-
async #peerConnected(
|
|
6448
|
-
debug(`peer connected: ${
|
|
6449
|
-
const peer = peernet.getConnection(
|
|
6447
|
+
async #peerConnected(peerId) {
|
|
6448
|
+
debug(`peer connected: ${peerId}`);
|
|
6449
|
+
const peer = peernet.getConnection(peerId);
|
|
6450
6450
|
if (!peer) {
|
|
6451
|
-
debug(`peer not found: ${
|
|
6451
|
+
debug(`peer not found: ${peerId}`);
|
|
6452
6452
|
return;
|
|
6453
6453
|
}
|
|
6454
6454
|
if (!peer.version) {
|
|
@@ -6463,13 +6463,13 @@ class Chain extends VersionControl {
|
|
|
6463
6463
|
peer.version = versionResponse.version;
|
|
6464
6464
|
}
|
|
6465
6465
|
if (!peer.version || typeof peer.version !== "string") {
|
|
6466
|
-
const reason = `invalid version response from peer ${
|
|
6466
|
+
const reason = `invalid version response from peer ${peerId}`;
|
|
6467
6467
|
debug(reason);
|
|
6468
|
-
await this.#recordPeerFailure(
|
|
6468
|
+
await this.#recordPeerFailure(peerId, reason);
|
|
6469
6469
|
return;
|
|
6470
6470
|
}
|
|
6471
|
-
} catch (
|
|
6472
|
-
debug(`failed to request version from peer ${
|
|
6471
|
+
} catch (error) {
|
|
6472
|
+
debug(`failed to request version from peer ${peerId}:`, error?.message ?? error);
|
|
6473
6473
|
return;
|
|
6474
6474
|
}
|
|
6475
6475
|
}
|
|
@@ -6477,7 +6477,7 @@ class Chain extends VersionControl {
|
|
|
6477
6477
|
if (!this.isVersionCompatible(peer.version)) {
|
|
6478
6478
|
const mismatchReason = `incompatible peer version ${peer.version} (local: ${this.version})`;
|
|
6479
6479
|
console.error(`[chain] ${mismatchReason}`);
|
|
6480
|
-
await this.#recordPeerFailure(
|
|
6480
|
+
await this.#recordPeerFailure(peerId, mismatchReason);
|
|
6481
6481
|
return;
|
|
6482
6482
|
}
|
|
6483
6483
|
let lastBlock;
|
|
@@ -6487,22 +6487,22 @@ class Chain extends VersionControl {
|
|
|
6487
6487
|
const lastBlockRaw = await this.#makeRequest(peer, "lastBlock");
|
|
6488
6488
|
console.log(new LastBlockMessage(lastBlockRaw));
|
|
6489
6489
|
lastBlock = new LastBlockMessage(lastBlockRaw).decoded;
|
|
6490
|
-
} catch (
|
|
6491
|
-
const
|
|
6492
|
-
debug(`lastBlock request failed: ${
|
|
6493
|
-
await this.#recordPeerFailure(
|
|
6490
|
+
} catch (error) {
|
|
6491
|
+
const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
|
|
6492
|
+
debug(`lastBlock request failed: ${peerName}:`, error?.message ?? error);
|
|
6493
|
+
await this.#recordPeerFailure(peerId, `lastBlock request failed: ${error?.message ?? error}`);
|
|
6494
6494
|
return;
|
|
6495
6495
|
}
|
|
6496
6496
|
const localBlock = await this.lastBlock;
|
|
6497
6497
|
const MAX_SYNC_AHEAD = 1e5;
|
|
6498
6498
|
if (lastBlock?.index > BigInt(localBlock?.index ?? 0) + BigInt(MAX_SYNC_AHEAD)) {
|
|
6499
|
-
const
|
|
6500
|
-
debug(`Peer ${
|
|
6501
|
-
await this.#recordPeerFailure(
|
|
6499
|
+
const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
|
|
6500
|
+
debug(`Peer ${peerName} claims unreasonable block height ${lastBlock.index} (local: ${localBlock?.index ?? 0})`);
|
|
6501
|
+
await this.#recordPeerFailure(peerId, `unreasonable lastBlock index: ${lastBlock.index}`);
|
|
6502
6502
|
return;
|
|
6503
6503
|
}
|
|
6504
6504
|
if (!lastBlock || !lastBlock.hash || lastBlock.hash === "0x0") {
|
|
6505
|
-
debug(`peer has no lastBlock: ${
|
|
6505
|
+
debug(`peer has no lastBlock: ${peerId}`);
|
|
6506
6506
|
return;
|
|
6507
6507
|
}
|
|
6508
6508
|
const higherThenCurrentLocal = !localBlock?.index ? true : lastBlock.index > localBlock.index;
|
|
@@ -6513,7 +6513,7 @@ class Chain extends VersionControl {
|
|
|
6513
6513
|
const knownBlocksResponse = await this.#decodeKnownBlocksResponse(knownBlocksRaw);
|
|
6514
6514
|
if (!knownBlocksResponse) {
|
|
6515
6515
|
debug(
|
|
6516
|
-
`knownBlocks decode failed for peer ${
|
|
6516
|
+
`knownBlocks decode failed for peer ${peerId} (non-fatal), continuing sync without prefilled wantList`
|
|
6517
6517
|
);
|
|
6518
6518
|
} else {
|
|
6519
6519
|
const MAX_WANTLIST_SIZE = 1e3;
|
|
@@ -6524,11 +6524,11 @@ class Chain extends VersionControl {
|
|
|
6524
6524
|
}
|
|
6525
6525
|
}
|
|
6526
6526
|
}
|
|
6527
|
-
} catch (
|
|
6528
|
-
const
|
|
6527
|
+
} catch (error) {
|
|
6528
|
+
const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
|
|
6529
6529
|
debug(
|
|
6530
|
-
`knownBlocks request failed: ${
|
|
6531
|
-
|
|
6530
|
+
`knownBlocks request failed: ${peerName} (non-fatal), continuing sync without prefilled wantList:`,
|
|
6531
|
+
error?.message ?? error
|
|
6532
6532
|
);
|
|
6533
6533
|
}
|
|
6534
6534
|
}
|
|
@@ -6545,9 +6545,9 @@ class Chain extends VersionControl {
|
|
|
6545
6545
|
try {
|
|
6546
6546
|
const peerTransactionPool = higherThenCurrentLocal && await this.getPeerTransactionPool(peer) || [];
|
|
6547
6547
|
if (this.#participating && peerTransactionPool.length > 0) return this.#runEpoch();
|
|
6548
|
-
} catch (
|
|
6549
|
-
const
|
|
6550
|
-
debug(`transactionPool request failed: ${
|
|
6548
|
+
} catch (error) {
|
|
6549
|
+
const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
|
|
6550
|
+
debug(`transactionPool request failed: ${peerName}:`, error?.message ?? error);
|
|
6551
6551
|
}
|
|
6552
6552
|
}, 3e3);
|
|
6553
6553
|
try {
|
|
@@ -6556,17 +6556,17 @@ class Chain extends VersionControl {
|
|
|
6556
6556
|
stateInfo = new StateMessage(stateInfo).decoded;
|
|
6557
6557
|
}
|
|
6558
6558
|
debug(
|
|
6559
|
-
`sync start with peer ${
|
|
6559
|
+
`sync start with peer ${peerId}: local=${localBlock?.index ?? -1} remote=${lastBlock?.index ?? -1} hash=${lastBlock?.hash}`
|
|
6560
6560
|
);
|
|
6561
6561
|
await this.syncChain(lastBlock);
|
|
6562
6562
|
debug(
|
|
6563
|
-
`sync finished with peer ${
|
|
6563
|
+
`sync finished with peer ${peerId}: state=${this.syncState} localNow=${(await this.lastBlock)?.index ?? -1}`
|
|
6564
6564
|
);
|
|
6565
6565
|
this.machine.states.info = stateInfo;
|
|
6566
|
-
} catch (
|
|
6567
|
-
const
|
|
6568
|
-
debug(`stateInfo/syncChain failed: ${
|
|
6569
|
-
await this.#recordPeerFailure(
|
|
6566
|
+
} catch (error) {
|
|
6567
|
+
const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
|
|
6568
|
+
debug(`stateInfo/syncChain failed: ${peerName}:`, error?.message ?? error);
|
|
6569
|
+
await this.#recordPeerFailure(peerId, `stateInfo/syncChain failed: ${error?.message ?? error}`);
|
|
6570
6570
|
return;
|
|
6571
6571
|
}
|
|
6572
6572
|
}
|
|
@@ -6582,19 +6582,16 @@ class Chain extends VersionControl {
|
|
|
6582
6582
|
try {
|
|
6583
6583
|
let result = await this.machine.execute(to, method, params);
|
|
6584
6584
|
globalThis.pubsub.publish(`transaction.completed.${hash}`, { status: "fulfilled", hash });
|
|
6585
|
-
|
|
6586
|
-
|
|
6587
|
-
error?.message ?? error
|
|
6588
|
-
);
|
|
6589
|
-
} catch (error2) {
|
|
6585
|
+
return result || "no state change";
|
|
6586
|
+
} catch (error) {
|
|
6590
6587
|
await transactionPoolStore.delete(hash);
|
|
6591
6588
|
try {
|
|
6592
6589
|
globalThis.peernet.publish("invalid-transaction", hash);
|
|
6593
6590
|
} catch (publishError) {
|
|
6594
6591
|
debug("peernet publish failed: invalid-transaction", publishError?.message ?? publishError);
|
|
6595
6592
|
}
|
|
6596
|
-
globalThis.pubsub.publish(`transaction.completed.${hash}`, { status: "fail", hash, error
|
|
6597
|
-
throw { error
|
|
6593
|
+
globalThis.pubsub.publish(`transaction.completed.${hash}`, { status: "fail", hash, error });
|
|
6594
|
+
throw { error, hash, from, to, params, nonce };
|
|
6598
6595
|
}
|
|
6599
6596
|
}
|
|
6600
6597
|
async #addBlock(block) {
|
|
@@ -6605,7 +6602,6 @@ class Chain extends VersionControl {
|
|
|
6605
6602
|
const existingBlockAtHeight = this.#blocks[blockIndex];
|
|
6606
6603
|
if (existingBlockAtHeight) {
|
|
6607
6604
|
if (existingBlockAtHeight.hash !== hash) {
|
|
6608
|
-
debug(`knownBlocks decode failed for peer ${peerId} (non-fatal), continuing sync without prefilled wantList`);
|
|
6609
6605
|
console.error(` Local: ${existingBlockAtHeight.hash}`);
|
|
6610
6606
|
console.error(` Remote: ${hash}`);
|
|
6611
6607
|
throw new Error(`Block conflict detected at index ${blockIndex}`);
|
|
@@ -6713,10 +6709,10 @@ class Chain extends VersionControl {
|
|
|
6713
6709
|
await this.updateState(blockMessage);
|
|
6714
6710
|
}
|
|
6715
6711
|
globalThis.pubsub.publish("block-processed", blockMessage.decoded);
|
|
6716
|
-
} catch (
|
|
6717
|
-
console.log(
|
|
6712
|
+
} catch (error) {
|
|
6713
|
+
console.log(error.hash);
|
|
6718
6714
|
console.log("errrrr");
|
|
6719
|
-
await transactionPoolStore.delete(
|
|
6715
|
+
await transactionPoolStore.delete(error.hash);
|
|
6720
6716
|
}
|
|
6721
6717
|
}
|
|
6722
6718
|
async participate(address) {
|
|
@@ -6734,12 +6730,12 @@ class Chain extends VersionControl {
|
|
|
6734
6730
|
const transaction = await signTransaction(rawTransaction, globalThis.peernet.identity);
|
|
6735
6731
|
try {
|
|
6736
6732
|
await this.sendTransaction(transaction);
|
|
6737
|
-
} catch (
|
|
6738
|
-
console.error(
|
|
6733
|
+
} catch (error) {
|
|
6734
|
+
console.error(error);
|
|
6739
6735
|
}
|
|
6740
6736
|
}
|
|
6741
|
-
} catch (
|
|
6742
|
-
debug("Error in participate:",
|
|
6737
|
+
} catch (error) {
|
|
6738
|
+
debug("Error in participate:", error.message);
|
|
6743
6739
|
}
|
|
6744
6740
|
if (await this.hasTransactionToHandle() && !this.#runningEpoch && this.#participating) await this.#runEpoch();
|
|
6745
6741
|
}
|
|
@@ -6836,9 +6832,9 @@ class Chain extends VersionControl {
|
|
|
6836
6832
|
address: validator,
|
|
6837
6833
|
bw: bw.up + bw.down
|
|
6838
6834
|
};
|
|
6839
|
-
} catch (
|
|
6840
|
-
const
|
|
6841
|
-
debug(`bw request failed: ${
|
|
6835
|
+
} catch (error) {
|
|
6836
|
+
const peerId = peer?.peerId || peer?.id || peer?.address || "unknown";
|
|
6837
|
+
debug(`bw request failed: ${peerId}:`, error?.message ?? error);
|
|
6842
6838
|
return null;
|
|
6843
6839
|
}
|
|
6844
6840
|
} else if (globalThis.peernet.selectedAccount === validator) {
|
|
@@ -6856,8 +6852,8 @@ class Chain extends VersionControl {
|
|
|
6856
6852
|
}
|
|
6857
6853
|
}
|
|
6858
6854
|
};
|
|
6859
|
-
finalizeBWAndBroadcast().catch((
|
|
6860
|
-
debug(`background BW finalization failed:`,
|
|
6855
|
+
finalizeBWAndBroadcast().catch((error) => {
|
|
6856
|
+
debug(`background BW finalization failed:`, error?.message ?? error);
|
|
6861
6857
|
});
|
|
6862
6858
|
block.validators = block.validators.map((validator) => {
|
|
6863
6859
|
validator.reward = block.fees;
|
|
@@ -6922,8 +6918,8 @@ class Chain extends VersionControl {
|
|
|
6922
6918
|
debug("peernet publish failed: consensus:propose", publishError?.message ?? publishError);
|
|
6923
6919
|
}
|
|
6924
6920
|
await this.#castVote("prevote", hash, block.index, this.#consensusRound);
|
|
6925
|
-
} catch (
|
|
6926
|
-
console.log(
|
|
6921
|
+
} catch (error) {
|
|
6922
|
+
console.log(error);
|
|
6927
6923
|
throw new Error(`invalid block ${block}`);
|
|
6928
6924
|
}
|
|
6929
6925
|
}
|
|
@@ -7054,8 +7050,8 @@ class Chain extends VersionControl {
|
|
|
7054
7050
|
if (globalThis.peernet && globalThis.peernet.start) {
|
|
7055
7051
|
await globalThis.peernet.start();
|
|
7056
7052
|
}
|
|
7057
|
-
} catch (
|
|
7058
|
-
console.warn("Failed to reconnect to peers:",
|
|
7053
|
+
} catch (error) {
|
|
7054
|
+
console.warn("Failed to reconnect to peers:", error.message);
|
|
7059
7055
|
}
|
|
7060
7056
|
}
|
|
7061
7057
|
}
|
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(
|
|
2343
|
-
if (!this.#peerReputations.has(
|
|
2344
|
-
this.#peerReputations.set(
|
|
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(
|
|
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 ${
|
|
2353
|
+
console.warn(`[peer-ban] Peer ${peerId} banned after ${rep.failures.length} failures`);
|
|
2354
2354
|
try {
|
|
2355
|
-
await globalThis.peernet.disconnect(
|
|
2355
|
+
await globalThis.peernet.disconnect(peerId);
|
|
2356
2356
|
} catch (e) {
|
|
2357
|
-
debug(`Failed to disconnect peer ${
|
|
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 (
|
|
2478
|
-
console.error(
|
|
2477
|
+
} catch (error) {
|
|
2478
|
+
console.error(error);
|
|
2479
2479
|
}
|
|
2480
2480
|
const end = Date.now();
|
|
2481
2481
|
console.log((end - start) / 1e3 + " s");
|
|
@@ -2590,10 +2590,10 @@ 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 (
|
|
2594
|
-
const
|
|
2595
|
-
debug(`peernet request failed: ${request} -> ${
|
|
2596
|
-
throw
|
|
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;
|
|
2597
2597
|
}
|
|
2598
2598
|
}
|
|
2599
2599
|
async #decodeKnownBlocksResponse(response) {
|
|
@@ -2657,8 +2657,8 @@ class Chain extends VersionControl {
|
|
|
2657
2657
|
let txData;
|
|
2658
2658
|
try {
|
|
2659
2659
|
txData = await globalThis.peernet.get(key, "transaction");
|
|
2660
|
-
} catch (
|
|
2661
|
-
debug(`Failed to get transaction ${key}:`,
|
|
2660
|
+
} catch (error) {
|
|
2661
|
+
debug(`Failed to get transaction ${key}:`, error?.message ?? error);
|
|
2662
2662
|
}
|
|
2663
2663
|
if (txData !== void 0) {
|
|
2664
2664
|
transactionsToGet.push(transactionPoolStore.put(key, txData));
|
|
@@ -2667,11 +2667,11 @@ class Chain extends VersionControl {
|
|
|
2667
2667
|
}
|
|
2668
2668
|
return Promise.all(transactionsToGet);
|
|
2669
2669
|
}
|
|
2670
|
-
async #peerConnected(
|
|
2671
|
-
debug(`peer connected: ${
|
|
2672
|
-
const peer = peernet.getConnection(
|
|
2670
|
+
async #peerConnected(peerId) {
|
|
2671
|
+
debug(`peer connected: ${peerId}`);
|
|
2672
|
+
const peer = peernet.getConnection(peerId);
|
|
2673
2673
|
if (!peer) {
|
|
2674
|
-
debug(`peer not found: ${
|
|
2674
|
+
debug(`peer not found: ${peerId}`);
|
|
2675
2675
|
return;
|
|
2676
2676
|
}
|
|
2677
2677
|
if (!peer.version) {
|
|
@@ -2686,13 +2686,13 @@ class Chain extends VersionControl {
|
|
|
2686
2686
|
peer.version = versionResponse.version;
|
|
2687
2687
|
}
|
|
2688
2688
|
if (!peer.version || typeof peer.version !== "string") {
|
|
2689
|
-
const reason = `invalid version response from peer ${
|
|
2689
|
+
const reason = `invalid version response from peer ${peerId}`;
|
|
2690
2690
|
debug(reason);
|
|
2691
|
-
await this.#recordPeerFailure(
|
|
2691
|
+
await this.#recordPeerFailure(peerId, reason);
|
|
2692
2692
|
return;
|
|
2693
2693
|
}
|
|
2694
|
-
} catch (
|
|
2695
|
-
debug(`failed to request version from peer ${
|
|
2694
|
+
} catch (error) {
|
|
2695
|
+
debug(`failed to request version from peer ${peerId}:`, error?.message ?? error);
|
|
2696
2696
|
return;
|
|
2697
2697
|
}
|
|
2698
2698
|
}
|
|
@@ -2700,7 +2700,7 @@ class Chain extends VersionControl {
|
|
|
2700
2700
|
if (!this.isVersionCompatible(peer.version)) {
|
|
2701
2701
|
const mismatchReason = `incompatible peer version ${peer.version} (local: ${this.version})`;
|
|
2702
2702
|
console.error(`[chain] ${mismatchReason}`);
|
|
2703
|
-
await this.#recordPeerFailure(
|
|
2703
|
+
await this.#recordPeerFailure(peerId, mismatchReason);
|
|
2704
2704
|
return;
|
|
2705
2705
|
}
|
|
2706
2706
|
let lastBlock;
|
|
@@ -2710,22 +2710,22 @@ class Chain extends VersionControl {
|
|
|
2710
2710
|
const lastBlockRaw = await this.#makeRequest(peer, "lastBlock");
|
|
2711
2711
|
console.log(new LastBlockMessage(lastBlockRaw));
|
|
2712
2712
|
lastBlock = new LastBlockMessage(lastBlockRaw).decoded;
|
|
2713
|
-
} catch (
|
|
2714
|
-
const
|
|
2715
|
-
debug(`lastBlock request failed: ${
|
|
2716
|
-
await this.#recordPeerFailure(
|
|
2713
|
+
} catch (error) {
|
|
2714
|
+
const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
|
|
2715
|
+
debug(`lastBlock request failed: ${peerName}:`, error?.message ?? error);
|
|
2716
|
+
await this.#recordPeerFailure(peerId, `lastBlock request failed: ${error?.message ?? error}`);
|
|
2717
2717
|
return;
|
|
2718
2718
|
}
|
|
2719
2719
|
const localBlock = await this.lastBlock;
|
|
2720
2720
|
const MAX_SYNC_AHEAD = 1e5;
|
|
2721
2721
|
if (lastBlock?.index > BigInt(localBlock?.index ?? 0) + BigInt(MAX_SYNC_AHEAD)) {
|
|
2722
|
-
const
|
|
2723
|
-
debug(`Peer ${
|
|
2724
|
-
await this.#recordPeerFailure(
|
|
2722
|
+
const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
|
|
2723
|
+
debug(`Peer ${peerName} claims unreasonable block height ${lastBlock.index} (local: ${localBlock?.index ?? 0})`);
|
|
2724
|
+
await this.#recordPeerFailure(peerId, `unreasonable lastBlock index: ${lastBlock.index}`);
|
|
2725
2725
|
return;
|
|
2726
2726
|
}
|
|
2727
2727
|
if (!lastBlock || !lastBlock.hash || lastBlock.hash === "0x0") {
|
|
2728
|
-
debug(`peer has no lastBlock: ${
|
|
2728
|
+
debug(`peer has no lastBlock: ${peerId}`);
|
|
2729
2729
|
return;
|
|
2730
2730
|
}
|
|
2731
2731
|
const higherThenCurrentLocal = !localBlock?.index ? true : lastBlock.index > localBlock.index;
|
|
@@ -2736,7 +2736,7 @@ class Chain extends VersionControl {
|
|
|
2736
2736
|
const knownBlocksResponse = await this.#decodeKnownBlocksResponse(knownBlocksRaw);
|
|
2737
2737
|
if (!knownBlocksResponse) {
|
|
2738
2738
|
debug(
|
|
2739
|
-
`knownBlocks decode failed for peer ${
|
|
2739
|
+
`knownBlocks decode failed for peer ${peerId} (non-fatal), continuing sync without prefilled wantList`
|
|
2740
2740
|
);
|
|
2741
2741
|
} else {
|
|
2742
2742
|
const MAX_WANTLIST_SIZE = 1e3;
|
|
@@ -2747,11 +2747,11 @@ class Chain extends VersionControl {
|
|
|
2747
2747
|
}
|
|
2748
2748
|
}
|
|
2749
2749
|
}
|
|
2750
|
-
} catch (
|
|
2751
|
-
const
|
|
2750
|
+
} catch (error) {
|
|
2751
|
+
const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
|
|
2752
2752
|
debug(
|
|
2753
|
-
`knownBlocks request failed: ${
|
|
2754
|
-
|
|
2753
|
+
`knownBlocks request failed: ${peerName} (non-fatal), continuing sync without prefilled wantList:`,
|
|
2754
|
+
error?.message ?? error
|
|
2755
2755
|
);
|
|
2756
2756
|
}
|
|
2757
2757
|
}
|
|
@@ -2768,9 +2768,9 @@ class Chain extends VersionControl {
|
|
|
2768
2768
|
try {
|
|
2769
2769
|
const peerTransactionPool = higherThenCurrentLocal && await this.getPeerTransactionPool(peer) || [];
|
|
2770
2770
|
if (this.#participating && peerTransactionPool.length > 0) return this.#runEpoch();
|
|
2771
|
-
} catch (
|
|
2772
|
-
const
|
|
2773
|
-
debug(`transactionPool request failed: ${
|
|
2771
|
+
} catch (error) {
|
|
2772
|
+
const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
|
|
2773
|
+
debug(`transactionPool request failed: ${peerName}:`, error?.message ?? error);
|
|
2774
2774
|
}
|
|
2775
2775
|
}, 3e3);
|
|
2776
2776
|
try {
|
|
@@ -2779,17 +2779,17 @@ class Chain extends VersionControl {
|
|
|
2779
2779
|
stateInfo = new StateMessage(stateInfo).decoded;
|
|
2780
2780
|
}
|
|
2781
2781
|
debug(
|
|
2782
|
-
`sync start with peer ${
|
|
2782
|
+
`sync start with peer ${peerId}: local=${localBlock?.index ?? -1} remote=${lastBlock?.index ?? -1} hash=${lastBlock?.hash}`
|
|
2783
2783
|
);
|
|
2784
2784
|
await this.syncChain(lastBlock);
|
|
2785
2785
|
debug(
|
|
2786
|
-
`sync finished with peer ${
|
|
2786
|
+
`sync finished with peer ${peerId}: state=${this.syncState} localNow=${(await this.lastBlock)?.index ?? -1}`
|
|
2787
2787
|
);
|
|
2788
2788
|
this.machine.states.info = stateInfo;
|
|
2789
|
-
} catch (
|
|
2790
|
-
const
|
|
2791
|
-
debug(`stateInfo/syncChain failed: ${
|
|
2792
|
-
await this.#recordPeerFailure(
|
|
2789
|
+
} catch (error) {
|
|
2790
|
+
const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
|
|
2791
|
+
debug(`stateInfo/syncChain failed: ${peerName}:`, error?.message ?? error);
|
|
2792
|
+
await this.#recordPeerFailure(peerId, `stateInfo/syncChain failed: ${error?.message ?? error}`);
|
|
2793
2793
|
return;
|
|
2794
2794
|
}
|
|
2795
2795
|
}
|
|
@@ -2805,19 +2805,16 @@ class Chain extends VersionControl {
|
|
|
2805
2805
|
try {
|
|
2806
2806
|
let result = await this.machine.execute(to, method, params);
|
|
2807
2807
|
globalThis.pubsub.publish(`transaction.completed.${hash}`, { status: "fulfilled", hash });
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
error?.message ?? error
|
|
2811
|
-
);
|
|
2812
|
-
} catch (error2) {
|
|
2808
|
+
return result || "no state change";
|
|
2809
|
+
} catch (error) {
|
|
2813
2810
|
await transactionPoolStore.delete(hash);
|
|
2814
2811
|
try {
|
|
2815
2812
|
globalThis.peernet.publish("invalid-transaction", hash);
|
|
2816
2813
|
} catch (publishError) {
|
|
2817
2814
|
debug("peernet publish failed: invalid-transaction", publishError?.message ?? publishError);
|
|
2818
2815
|
}
|
|
2819
|
-
globalThis.pubsub.publish(`transaction.completed.${hash}`, { status: "fail", hash, error
|
|
2820
|
-
throw { error
|
|
2816
|
+
globalThis.pubsub.publish(`transaction.completed.${hash}`, { status: "fail", hash, error });
|
|
2817
|
+
throw { error, hash, from, to, params, nonce };
|
|
2821
2818
|
}
|
|
2822
2819
|
}
|
|
2823
2820
|
async #addBlock(block) {
|
|
@@ -2828,7 +2825,6 @@ class Chain extends VersionControl {
|
|
|
2828
2825
|
const existingBlockAtHeight = this.#blocks[blockIndex];
|
|
2829
2826
|
if (existingBlockAtHeight) {
|
|
2830
2827
|
if (existingBlockAtHeight.hash !== hash) {
|
|
2831
|
-
debug(`knownBlocks decode failed for peer ${peerId} (non-fatal), continuing sync without prefilled wantList`);
|
|
2832
2828
|
console.error(` Local: ${existingBlockAtHeight.hash}`);
|
|
2833
2829
|
console.error(` Remote: ${hash}`);
|
|
2834
2830
|
throw new Error(`Block conflict detected at index ${blockIndex}`);
|
|
@@ -2936,10 +2932,10 @@ class Chain extends VersionControl {
|
|
|
2936
2932
|
await this.updateState(blockMessage);
|
|
2937
2933
|
}
|
|
2938
2934
|
globalThis.pubsub.publish("block-processed", blockMessage.decoded);
|
|
2939
|
-
} catch (
|
|
2940
|
-
console.log(
|
|
2935
|
+
} catch (error) {
|
|
2936
|
+
console.log(error.hash);
|
|
2941
2937
|
console.log("errrrr");
|
|
2942
|
-
await transactionPoolStore.delete(
|
|
2938
|
+
await transactionPoolStore.delete(error.hash);
|
|
2943
2939
|
}
|
|
2944
2940
|
}
|
|
2945
2941
|
async participate(address) {
|
|
@@ -2957,12 +2953,12 @@ class Chain extends VersionControl {
|
|
|
2957
2953
|
const transaction = await signTransaction(rawTransaction, globalThis.peernet.identity);
|
|
2958
2954
|
try {
|
|
2959
2955
|
await this.sendTransaction(transaction);
|
|
2960
|
-
} catch (
|
|
2961
|
-
console.error(
|
|
2956
|
+
} catch (error) {
|
|
2957
|
+
console.error(error);
|
|
2962
2958
|
}
|
|
2963
2959
|
}
|
|
2964
|
-
} catch (
|
|
2965
|
-
debug("Error in participate:",
|
|
2960
|
+
} catch (error) {
|
|
2961
|
+
debug("Error in participate:", error.message);
|
|
2966
2962
|
}
|
|
2967
2963
|
if (await this.hasTransactionToHandle() && !this.#runningEpoch && this.#participating) await this.#runEpoch();
|
|
2968
2964
|
}
|
|
@@ -3059,9 +3055,9 @@ class Chain extends VersionControl {
|
|
|
3059
3055
|
address: validator,
|
|
3060
3056
|
bw: bw.up + bw.down
|
|
3061
3057
|
};
|
|
3062
|
-
} catch (
|
|
3063
|
-
const
|
|
3064
|
-
debug(`bw request failed: ${
|
|
3058
|
+
} catch (error) {
|
|
3059
|
+
const peerId = peer?.peerId || peer?.id || peer?.address || "unknown";
|
|
3060
|
+
debug(`bw request failed: ${peerId}:`, error?.message ?? error);
|
|
3065
3061
|
return null;
|
|
3066
3062
|
}
|
|
3067
3063
|
} else if (globalThis.peernet.selectedAccount === validator) {
|
|
@@ -3079,8 +3075,8 @@ class Chain extends VersionControl {
|
|
|
3079
3075
|
}
|
|
3080
3076
|
}
|
|
3081
3077
|
};
|
|
3082
|
-
finalizeBWAndBroadcast().catch((
|
|
3083
|
-
debug(`background BW finalization failed:`,
|
|
3078
|
+
finalizeBWAndBroadcast().catch((error) => {
|
|
3079
|
+
debug(`background BW finalization failed:`, error?.message ?? error);
|
|
3084
3080
|
});
|
|
3085
3081
|
block.validators = block.validators.map((validator) => {
|
|
3086
3082
|
validator.reward = block.fees;
|
|
@@ -3145,8 +3141,8 @@ class Chain extends VersionControl {
|
|
|
3145
3141
|
debug("peernet publish failed: consensus:propose", publishError?.message ?? publishError);
|
|
3146
3142
|
}
|
|
3147
3143
|
await this.#castVote("prevote", hash, block.index, this.#consensusRound);
|
|
3148
|
-
} catch (
|
|
3149
|
-
console.log(
|
|
3144
|
+
} catch (error) {
|
|
3145
|
+
console.log(error);
|
|
3150
3146
|
throw new Error(`invalid block ${block}`);
|
|
3151
3147
|
}
|
|
3152
3148
|
}
|
|
@@ -3277,8 +3273,8 @@ class Chain extends VersionControl {
|
|
|
3277
3273
|
if (globalThis.peernet && globalThis.peernet.start) {
|
|
3278
3274
|
await globalThis.peernet.start();
|
|
3279
3275
|
}
|
|
3280
|
-
} catch (
|
|
3281
|
-
console.warn("Failed to reconnect to peers:",
|
|
3276
|
+
} catch (error) {
|
|
3277
|
+
console.warn("Failed to reconnect to peers:", error.message);
|
|
3282
3278
|
}
|
|
3283
3279
|
}
|
|
3284
3280
|
}
|