@leofcoin/chain 1.4.33 → 1.4.35
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/chain.js +37 -17
- package/exports/typings/chain.d.ts +2 -0
- package/package.json +1 -1
package/exports/chain.js
CHANGED
|
@@ -457,6 +457,7 @@ class Chain extends Contract {
|
|
|
457
457
|
#validators = [];
|
|
458
458
|
/** {Block[]} */
|
|
459
459
|
#blocks = [];
|
|
460
|
+
#blockHashMap = new Map();
|
|
460
461
|
#machine;
|
|
461
462
|
/** {Boolean} */
|
|
462
463
|
#runningEpoch = false;
|
|
@@ -610,7 +611,7 @@ class Chain extends Contract {
|
|
|
610
611
|
let promises = [];
|
|
611
612
|
let data = await new peernet.protos['peernet-request']({ request: 'lastBlock' });
|
|
612
613
|
let node = await peernet.prepareMessage(data);
|
|
613
|
-
for (const peer of peernet
|
|
614
|
+
for (const peer of peernet?.connections) {
|
|
614
615
|
if (peer.connected && peer.readyState === 'open' && peer.peerId !== this.id) {
|
|
615
616
|
promises.push(async () => {
|
|
616
617
|
try {
|
|
@@ -682,8 +683,10 @@ class Chain extends Contract {
|
|
|
682
683
|
this.#lastBlock = { ...localBlock.decoded, hash: await localBlock.hash() };
|
|
683
684
|
}
|
|
684
685
|
else {
|
|
685
|
-
|
|
686
|
-
|
|
686
|
+
if (globalThis.peernet?.connections.length > 0) {
|
|
687
|
+
const latestBlock = await this.#getLatestBlock();
|
|
688
|
+
await this.#syncChain(latestBlock);
|
|
689
|
+
}
|
|
687
690
|
}
|
|
688
691
|
}
|
|
689
692
|
catch (error) {
|
|
@@ -713,7 +716,7 @@ class Chain extends Contract {
|
|
|
713
716
|
return { has, address };
|
|
714
717
|
}));
|
|
715
718
|
promises = promises.filter(({ status, value }) => status === 'fulfilled' && !value.has);
|
|
716
|
-
await Promise.allSettled(promises.map(({ value }) =>
|
|
719
|
+
await Promise.allSettled(promises.map(({ value }) => this.getAndPutBlock(value.address)));
|
|
717
720
|
}
|
|
718
721
|
if (!this.lastBlock || Number(this.lastBlock.index) < Number(lastBlock.index)) {
|
|
719
722
|
// TODO: check if valid
|
|
@@ -722,7 +725,6 @@ class Chain extends Contract {
|
|
|
722
725
|
await this.resolveBlock(lastBlock.hash);
|
|
723
726
|
let blocksSynced = localIndex > 0 ? (localIndex > index ? localIndex - index : index - localIndex) : index;
|
|
724
727
|
debug(`synced ${blocksSynced} ${blocksSynced > 1 ? 'blocks' : 'block'}`);
|
|
725
|
-
this.#blocks.length;
|
|
726
728
|
const start = (this.#blocks.length - blocksSynced) - 1;
|
|
727
729
|
await this.#loadBlocks(this.blocks.slice(start));
|
|
728
730
|
await this.#updateState(new BlockMessage(this.#blocks[this.#blocks.length - 1]));
|
|
@@ -750,22 +752,40 @@ class Chain extends Contract {
|
|
|
750
752
|
async #knownBlocksHandler() {
|
|
751
753
|
return new peernet.protos['peernet-response']({ response: { blocks: this.#blocks.map((block) => block.hash) } });
|
|
752
754
|
}
|
|
753
|
-
async
|
|
754
|
-
if (!hash)
|
|
755
|
-
throw new Error(`expected hash, got: ${hash}`);
|
|
755
|
+
async getAndPutBlock(hash) {
|
|
756
756
|
let block = await peernet.get(hash, 'block');
|
|
757
757
|
block = await new BlockMessage(block);
|
|
758
|
+
const { index } = block.decoded;
|
|
759
|
+
if (this.#blocks[index] && this.#blocks[index].hash !== block.hash)
|
|
760
|
+
throw `invalid block ${hash} @${index}`;
|
|
758
761
|
if (!await peernet.has(hash, 'block'))
|
|
759
762
|
await peernet.put(hash, block.encoded, 'block');
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
if (
|
|
764
|
-
throw `
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
763
|
+
return block;
|
|
764
|
+
}
|
|
765
|
+
async resolveBlock(hash) {
|
|
766
|
+
if (!hash)
|
|
767
|
+
throw new Error(`expected hash, got: ${hash}`);
|
|
768
|
+
const index = this.#blockHashMap.get(hash);
|
|
769
|
+
if (this.#blocks[index]) {
|
|
770
|
+
if (this.#blocks[index].previousHash !== '0x0') {
|
|
771
|
+
return this.resolveBlock(this.#blocks[index]);
|
|
772
|
+
}
|
|
773
|
+
return;
|
|
774
|
+
}
|
|
775
|
+
try {
|
|
776
|
+
const block = await this.getAndPutBlock(hash);
|
|
777
|
+
const { previousHash, index } = block.decoded;
|
|
778
|
+
const size = block.encoded.length > 0 ? block.encoded.length : block.encoded.byteLength;
|
|
779
|
+
this.#totalSize += size;
|
|
780
|
+
this.#blocks[index] = { hash, ...block.decoded };
|
|
781
|
+
this.#blockHashMap.set(hash, index);
|
|
782
|
+
console.log(`resolved block: ${hash} @${index} ${formatBytes(size)}`);
|
|
783
|
+
if (previousHash !== '0x0') {
|
|
784
|
+
return this.resolveBlock(previousHash);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
catch (error) {
|
|
788
|
+
console.error(error);
|
|
769
789
|
}
|
|
770
790
|
}
|
|
771
791
|
async resolveBlocks() {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BlockMessage } from '@leofcoin/messages';
|
|
1
2
|
import Contract from './contract.js';
|
|
2
3
|
import { BigNumberish } from '@ethersproject/bignumber';
|
|
3
4
|
export default class Chain extends Contract {
|
|
@@ -25,6 +26,7 @@ export default class Chain extends Contract {
|
|
|
25
26
|
hash: string;
|
|
26
27
|
previousHash: string;
|
|
27
28
|
}>;
|
|
29
|
+
getAndPutBlock(hash: string): BlockMessage;
|
|
28
30
|
resolveBlock(hash: any): any;
|
|
29
31
|
resolveBlocks(): any;
|
|
30
32
|
participate(address: any): Promise<void>;
|