@leofcoin/chain 1.4.75 → 1.4.76

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.
@@ -1818,7 +1818,33 @@ class Machine {
1818
1818
  }
1819
1819
  }
1820
1820
 
1821
- const queue = new PQueue({ concurrency: 1, throwOnTimeout: true });
1821
+ class Jobber {
1822
+ timeout;
1823
+ busy = false;
1824
+ stop;
1825
+ constructor(timeout) {
1826
+ this.timeout = timeout;
1827
+ }
1828
+ add(fn) {
1829
+ this.busy = true;
1830
+ return new Promise(async (resolve, reject) => {
1831
+ const timeout = setTimeout(() => {
1832
+ reject('timeout');
1833
+ }, this.timeout);
1834
+ this.stop = () => {
1835
+ clearTimeout(timeout);
1836
+ this.busy = false;
1837
+ resolve('stopped');
1838
+ };
1839
+ const result = await fn();
1840
+ clearTimeout(timeout);
1841
+ this.busy = false;
1842
+ resolve(result);
1843
+ });
1844
+ }
1845
+ }
1846
+
1847
+ new PQueue({ concurrency: 1, throwOnTimeout: true });
1822
1848
  class State extends Contract {
1823
1849
  #resolveErrored;
1824
1850
  #lastResolvedTime;
@@ -1832,9 +1858,16 @@ class State extends Contract {
1832
1858
  #chainSyncing = false;
1833
1859
  #lastBlock = { index: 0, hash: '0x0', previousHash: '0x0' };
1834
1860
  #blocks = [];
1835
- #knownBlocks = [];
1861
+ knownBlocks = [];
1836
1862
  #totalSize = 0;
1837
1863
  #machine;
1864
+ #loaded = false;
1865
+ get loaded() {
1866
+ return this.#loaded;
1867
+ }
1868
+ get resolving() {
1869
+ return this.#resolving;
1870
+ }
1838
1871
  /**
1839
1872
  * amount the native token has been iteracted with
1840
1873
  */
@@ -1889,6 +1922,7 @@ class State extends Contract {
1889
1922
  super();
1890
1923
  }
1891
1924
  async init() {
1925
+ this.jobber = new Jobber(30_000);
1892
1926
  if (super.init)
1893
1927
  await super.init();
1894
1928
  await globalThis.peernet.addRequestHandler('lastBlock', this.#lastBlockHandler.bind(this));
@@ -1961,18 +1995,27 @@ class State extends Contract {
1961
1995
  return;
1962
1996
  }
1963
1997
  }
1964
- const block = await this.getAndPutBlock(hash);
1965
- index = block.decoded.index;
1966
- const size = block.encoded.length > 0 ? block.encoded.length : block.encoded.byteLength;
1967
- this.#totalSize += size;
1968
- this.#blocks[index] = { hash, ...block.decoded };
1969
- this.#blockHashMap.set(hash, index);
1970
- globalThis.debug(`resolved block: ${hash} @${index} ${formatBytes(size)}`);
1971
- this.#lastResolved = this.#blocks[index];
1972
- this.#lastResolvedTime = Date.now();
1998
+ try {
1999
+ const block = await this.getAndPutBlock(hash);
2000
+ index = block.decoded.index;
2001
+ const size = block.encoded.length > 0 ? block.encoded.length : block.encoded.byteLength;
2002
+ this.#totalSize += size;
2003
+ this.#blocks[index] = { hash, ...block.decoded };
2004
+ this.#blockHashMap.set(hash, index);
2005
+ globalThis.debug(`resolved block: ${hash} @${index} ${formatBytes(size)}`);
2006
+ this.#lastResolved = this.#blocks[index];
2007
+ this.#lastResolvedTime = Date.now();
2008
+ }
2009
+ catch (error) {
2010
+ this.#resolving = false;
2011
+ this.#chainSyncing = false;
2012
+ throw new Error('resolve error');
2013
+ }
1973
2014
  return;
1974
2015
  }
1975
2016
  async resolveBlock(hash) {
2017
+ if (this.#resolveErrorCount === 3)
2018
+ this.#resolveErrorCount = 0;
1976
2019
  if (!hash)
1977
2020
  throw new Error(`expected hash, got: ${hash}`);
1978
2021
  if (hash === '0x0')
@@ -1980,19 +2023,36 @@ class State extends Contract {
1980
2023
  if (this.#resolving)
1981
2024
  return 'already resolving';
1982
2025
  this.#resolving = true;
1983
- await queue.add(() => this.#resolveBlock(hash));
1984
- this.#resolving = false;
1985
- if (!this.#blockHashMap.has(this.#lastResolved.previousHash) && this.#lastResolved.previousHash !== '0x0')
1986
- return this.resolveBlock(this.#lastResolved.previousHash);
1987
- return;
2026
+ try {
2027
+ await this.jobber.add(() => this.#resolveBlock(hash));
2028
+ this.#resolving = false;
2029
+ if (!this.#blockHashMap.has(this.#lastResolved.previousHash) && this.#lastResolved.previousHash !== '0x0')
2030
+ return this.resolveBlock(this.#lastResolved.previousHash);
2031
+ }
2032
+ catch (error) {
2033
+ this.#resolveErrorCount += 1;
2034
+ if (this.#resolveErrorCount < 3)
2035
+ return this.resolveBlock(hash);
2036
+ else
2037
+ throw new Error('resolve errored');
2038
+ }
1988
2039
  }
1989
2040
  async resolveBlocks() {
2041
+ try {
2042
+ if (this.jobber.busy && this.jobber.stop) {
2043
+ await this.jobber.stop();
2044
+ }
2045
+ }
2046
+ catch (error) {
2047
+ console.error(error);
2048
+ }
1990
2049
  try {
1991
2050
  const localBlock = await globalThis.chainStore.get('lastBlock');
1992
2051
  const hash = new TextDecoder().decode(localBlock);
1993
- if (hash && hash !== '0x0')
2052
+ if (hash && hash !== '0x0') {
1994
2053
  await this.resolveBlock(hash);
1995
- this.#lastBlock = this.#blocks[this.#blocks.length - 1];
2054
+ this.#lastBlock = this.#blocks[this.#blocks.length - 1];
2055
+ }
1996
2056
  }
1997
2057
  catch {
1998
2058
  this.#resolveErrored = true;
@@ -2005,7 +2065,15 @@ class State extends Contract {
2005
2065
  if (!this.shouldSync) {
2006
2066
  return;
2007
2067
  }
2008
- await queue.clear();
2068
+ try {
2069
+ if (this.jobber.busy && this.jobber.stop) {
2070
+ await this.jobber.stop();
2071
+ }
2072
+ }
2073
+ catch (error) {
2074
+ console.error(error);
2075
+ }
2076
+ // await queue.clear()
2009
2077
  this.#chainSyncing = true;
2010
2078
  if (!lastBlock)
2011
2079
  lastBlock = await this.#getLatestBlock();
@@ -2033,9 +2101,9 @@ class State extends Contract {
2033
2101
  }
2034
2102
  async #syncChain(lastBlock) {
2035
2103
  try {
2036
- if (this.#knownBlocks?.length === Number(lastBlock.index) + 1) {
2104
+ if (this.knownBlocks?.length === Number(lastBlock.index) + 1) {
2037
2105
  let promises = [];
2038
- promises = await Promise.allSettled(this.#knownBlocks.map(async (address) => {
2106
+ promises = await Promise.allSettled(this.knownBlocks.map(async (address) => {
2039
2107
  const has = await globalThis.peernet.has(address, 'block');
2040
2108
  return { has, address };
2041
2109
  }));
@@ -2067,15 +2135,16 @@ class State extends Contract {
2067
2135
  let node = await globalThis.peernet.prepareMessage(data);
2068
2136
  for (const peer of globalThis.peernet?.connections) {
2069
2137
  if (peer.connected && peer.version === this.version) {
2070
- promises.push(async () => {
2138
+ const task = async () => {
2071
2139
  try {
2072
2140
  const result = await peer.request(node.encoded);
2073
- return { result, peer };
2141
+ return { result: Uint8Array.from(Object.values(result)), peer };
2074
2142
  }
2075
2143
  catch (error) {
2076
2144
  throw error;
2077
2145
  }
2078
- });
2146
+ };
2147
+ promises.push(task());
2079
2148
  }
2080
2149
  }
2081
2150
  promises = await this.promiseRequests(promises);
@@ -2096,7 +2165,7 @@ class State extends Contract {
2096
2165
  let node = await globalThis.peernet.prepareMessage(data);
2097
2166
  let message = await peer.request(node);
2098
2167
  message = await new globalThis.peernet.protos['peernet-response'](message);
2099
- this.#knownBlocks = message.decoded.response;
2168
+ this.knownBlocks = message.decoded.response;
2100
2169
  }
2101
2170
  }
2102
2171
  return latest;
@@ -2109,6 +2178,8 @@ class State extends Contract {
2109
2178
  let poolTransactionKeys = await globalThis.transactionPoolStore.keys();
2110
2179
  for (const block of blocks) {
2111
2180
  if (block && !block.loaded) {
2181
+ if (block.index === 0)
2182
+ this.#loaded = true;
2112
2183
  for (const transaction of block.transactions) {
2113
2184
  if (poolTransactionKeys.includes(transaction.hash))
2114
2185
  await globalThis.transactionPoolStore.delete(transaction.hash);
@@ -2147,7 +2218,8 @@ class State extends Contract {
2147
2218
  clearTimeout(timeout);
2148
2219
  if (promises.length > 0) {
2149
2220
  promises = promises.map(async ({ value }) => {
2150
- const node = await new globalThis.peernet.protos['peernet-response'](value);
2221
+ console.log(value);
2222
+ const node = await new globalThis.peernet.protos['peernet-response'](value.result);
2151
2223
  return { value: node.decoded.response, peer: value.peer };
2152
2224
  });
2153
2225
  promises = await Promise.all(promises);
@@ -2325,8 +2397,8 @@ class Chain extends State {
2325
2397
  return;
2326
2398
  const lastBlock = await this.#makeRequest(peer, 'lastBlock');
2327
2399
  if (Object.keys(lastBlock).length > 0) {
2328
- if (!this.lastBlock || !this.blocks[this.blocks.length - 1].loaded || lastBlock && lastBlock.index > this.lastBlock?.index) {
2329
- // this.#knownBlocks = await this.#makeRequest(peer, 'knownBlocks')
2400
+ if (!this.lastBlock || !this.blocks[this.blocks.length - 1]?.loaded || lastBlock && lastBlock.index > this.lastBlock?.index || !this.loaded && !this.resolving) {
2401
+ this.knownBlocks = await this.#makeRequest(peer, 'knownBlocks');
2330
2402
  await this.syncChain(lastBlock);
2331
2403
  // if (await this.hasTransactionToHandle() && this.#participating) this.#runEpoch()
2332
2404
  }
package/exports/chain.js CHANGED
@@ -444,7 +444,33 @@ class Machine {
444
444
  }
445
445
  }
446
446
 
447
- const queue = new PQueue({ concurrency: 1, throwOnTimeout: true });
447
+ class Jobber {
448
+ timeout;
449
+ busy = false;
450
+ stop;
451
+ constructor(timeout) {
452
+ this.timeout = timeout;
453
+ }
454
+ add(fn) {
455
+ this.busy = true;
456
+ return new Promise(async (resolve, reject) => {
457
+ const timeout = setTimeout(() => {
458
+ reject('timeout');
459
+ }, this.timeout);
460
+ this.stop = () => {
461
+ clearTimeout(timeout);
462
+ this.busy = false;
463
+ resolve('stopped');
464
+ };
465
+ const result = await fn();
466
+ clearTimeout(timeout);
467
+ this.busy = false;
468
+ resolve(result);
469
+ });
470
+ }
471
+ }
472
+
473
+ new PQueue({ concurrency: 1, throwOnTimeout: true });
448
474
  class State extends Contract {
449
475
  #resolveErrored;
450
476
  #lastResolvedTime;
@@ -458,9 +484,16 @@ class State extends Contract {
458
484
  #chainSyncing = false;
459
485
  #lastBlock = { index: 0, hash: '0x0', previousHash: '0x0' };
460
486
  #blocks = [];
461
- #knownBlocks = [];
487
+ knownBlocks = [];
462
488
  #totalSize = 0;
463
489
  #machine;
490
+ #loaded = false;
491
+ get loaded() {
492
+ return this.#loaded;
493
+ }
494
+ get resolving() {
495
+ return this.#resolving;
496
+ }
464
497
  /**
465
498
  * amount the native token has been iteracted with
466
499
  */
@@ -515,6 +548,7 @@ class State extends Contract {
515
548
  super();
516
549
  }
517
550
  async init() {
551
+ this.jobber = new Jobber(30_000);
518
552
  if (super.init)
519
553
  await super.init();
520
554
  await globalThis.peernet.addRequestHandler('lastBlock', this.#lastBlockHandler.bind(this));
@@ -587,18 +621,27 @@ class State extends Contract {
587
621
  return;
588
622
  }
589
623
  }
590
- const block = await this.getAndPutBlock(hash);
591
- index = block.decoded.index;
592
- const size = block.encoded.length > 0 ? block.encoded.length : block.encoded.byteLength;
593
- this.#totalSize += size;
594
- this.#blocks[index] = { hash, ...block.decoded };
595
- this.#blockHashMap.set(hash, index);
596
- globalThis.debug(`resolved block: ${hash} @${index} ${formatBytes(size)}`);
597
- this.#lastResolved = this.#blocks[index];
598
- this.#lastResolvedTime = Date.now();
624
+ try {
625
+ const block = await this.getAndPutBlock(hash);
626
+ index = block.decoded.index;
627
+ const size = block.encoded.length > 0 ? block.encoded.length : block.encoded.byteLength;
628
+ this.#totalSize += size;
629
+ this.#blocks[index] = { hash, ...block.decoded };
630
+ this.#blockHashMap.set(hash, index);
631
+ globalThis.debug(`resolved block: ${hash} @${index} ${formatBytes(size)}`);
632
+ this.#lastResolved = this.#blocks[index];
633
+ this.#lastResolvedTime = Date.now();
634
+ }
635
+ catch (error) {
636
+ this.#resolving = false;
637
+ this.#chainSyncing = false;
638
+ throw new Error('resolve error');
639
+ }
599
640
  return;
600
641
  }
601
642
  async resolveBlock(hash) {
643
+ if (this.#resolveErrorCount === 3)
644
+ this.#resolveErrorCount = 0;
602
645
  if (!hash)
603
646
  throw new Error(`expected hash, got: ${hash}`);
604
647
  if (hash === '0x0')
@@ -606,19 +649,36 @@ class State extends Contract {
606
649
  if (this.#resolving)
607
650
  return 'already resolving';
608
651
  this.#resolving = true;
609
- await queue.add(() => this.#resolveBlock(hash));
610
- this.#resolving = false;
611
- if (!this.#blockHashMap.has(this.#lastResolved.previousHash) && this.#lastResolved.previousHash !== '0x0')
612
- return this.resolveBlock(this.#lastResolved.previousHash);
613
- return;
652
+ try {
653
+ await this.jobber.add(() => this.#resolveBlock(hash));
654
+ this.#resolving = false;
655
+ if (!this.#blockHashMap.has(this.#lastResolved.previousHash) && this.#lastResolved.previousHash !== '0x0')
656
+ return this.resolveBlock(this.#lastResolved.previousHash);
657
+ }
658
+ catch (error) {
659
+ this.#resolveErrorCount += 1;
660
+ if (this.#resolveErrorCount < 3)
661
+ return this.resolveBlock(hash);
662
+ else
663
+ throw new Error('resolve errored');
664
+ }
614
665
  }
615
666
  async resolveBlocks() {
667
+ try {
668
+ if (this.jobber.busy && this.jobber.stop) {
669
+ await this.jobber.stop();
670
+ }
671
+ }
672
+ catch (error) {
673
+ console.error(error);
674
+ }
616
675
  try {
617
676
  const localBlock = await globalThis.chainStore.get('lastBlock');
618
677
  const hash = new TextDecoder().decode(localBlock);
619
- if (hash && hash !== '0x0')
678
+ if (hash && hash !== '0x0') {
620
679
  await this.resolveBlock(hash);
621
- this.#lastBlock = this.#blocks[this.#blocks.length - 1];
680
+ this.#lastBlock = this.#blocks[this.#blocks.length - 1];
681
+ }
622
682
  }
623
683
  catch {
624
684
  this.#resolveErrored = true;
@@ -631,7 +691,15 @@ class State extends Contract {
631
691
  if (!this.shouldSync) {
632
692
  return;
633
693
  }
634
- await queue.clear();
694
+ try {
695
+ if (this.jobber.busy && this.jobber.stop) {
696
+ await this.jobber.stop();
697
+ }
698
+ }
699
+ catch (error) {
700
+ console.error(error);
701
+ }
702
+ // await queue.clear()
635
703
  this.#chainSyncing = true;
636
704
  if (!lastBlock)
637
705
  lastBlock = await this.#getLatestBlock();
@@ -659,9 +727,9 @@ class State extends Contract {
659
727
  }
660
728
  async #syncChain(lastBlock) {
661
729
  try {
662
- if (this.#knownBlocks?.length === Number(lastBlock.index) + 1) {
730
+ if (this.knownBlocks?.length === Number(lastBlock.index) + 1) {
663
731
  let promises = [];
664
- promises = await Promise.allSettled(this.#knownBlocks.map(async (address) => {
732
+ promises = await Promise.allSettled(this.knownBlocks.map(async (address) => {
665
733
  const has = await globalThis.peernet.has(address, 'block');
666
734
  return { has, address };
667
735
  }));
@@ -693,15 +761,16 @@ class State extends Contract {
693
761
  let node = await globalThis.peernet.prepareMessage(data);
694
762
  for (const peer of globalThis.peernet?.connections) {
695
763
  if (peer.connected && peer.version === this.version) {
696
- promises.push(async () => {
764
+ const task = async () => {
697
765
  try {
698
766
  const result = await peer.request(node.encoded);
699
- return { result, peer };
767
+ return { result: Uint8Array.from(Object.values(result)), peer };
700
768
  }
701
769
  catch (error) {
702
770
  throw error;
703
771
  }
704
- });
772
+ };
773
+ promises.push(task());
705
774
  }
706
775
  }
707
776
  promises = await this.promiseRequests(promises);
@@ -722,7 +791,7 @@ class State extends Contract {
722
791
  let node = await globalThis.peernet.prepareMessage(data);
723
792
  let message = await peer.request(node);
724
793
  message = await new globalThis.peernet.protos['peernet-response'](message);
725
- this.#knownBlocks = message.decoded.response;
794
+ this.knownBlocks = message.decoded.response;
726
795
  }
727
796
  }
728
797
  return latest;
@@ -735,6 +804,8 @@ class State extends Contract {
735
804
  let poolTransactionKeys = await globalThis.transactionPoolStore.keys();
736
805
  for (const block of blocks) {
737
806
  if (block && !block.loaded) {
807
+ if (block.index === 0)
808
+ this.#loaded = true;
738
809
  for (const transaction of block.transactions) {
739
810
  if (poolTransactionKeys.includes(transaction.hash))
740
811
  await globalThis.transactionPoolStore.delete(transaction.hash);
@@ -773,7 +844,8 @@ class State extends Contract {
773
844
  clearTimeout(timeout);
774
845
  if (promises.length > 0) {
775
846
  promises = promises.map(async ({ value }) => {
776
- const node = await new globalThis.peernet.protos['peernet-response'](value);
847
+ console.log(value);
848
+ const node = await new globalThis.peernet.protos['peernet-response'](value.result);
777
849
  return { value: node.decoded.response, peer: value.peer };
778
850
  });
779
851
  promises = await Promise.all(promises);
@@ -951,8 +1023,8 @@ class Chain extends State {
951
1023
  return;
952
1024
  const lastBlock = await this.#makeRequest(peer, 'lastBlock');
953
1025
  if (Object.keys(lastBlock).length > 0) {
954
- if (!this.lastBlock || !this.blocks[this.blocks.length - 1].loaded || lastBlock && lastBlock.index > this.lastBlock?.index) {
955
- // this.#knownBlocks = await this.#makeRequest(peer, 'knownBlocks')
1026
+ if (!this.lastBlock || !this.blocks[this.blocks.length - 1]?.loaded || lastBlock && lastBlock.index > this.lastBlock?.index || !this.loaded && !this.resolving) {
1027
+ this.knownBlocks = await this.#makeRequest(peer, 'knownBlocks');
956
1028
  await this.syncChain(lastBlock);
957
1029
  // if (await this.hasTransactionToHandle() && this.#participating) this.#runEpoch()
958
1030
  }
@@ -0,0 +1,7 @@
1
+ export default class Jobber {
2
+ timeout: EpochTimeStamp;
3
+ busy: boolean;
4
+ stop: Function;
5
+ constructor(timeout: any);
6
+ add(fn: any): Promise<unknown>;
7
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leofcoin/chain",
3
- "version": "1.4.75",
3
+ "version": "1.4.76",
4
4
  "description": "Official javascript implementation",
5
5
  "exports": {
6
6
  "./node": "./exports/node.js",
@@ -1,3 +0,0 @@
1
- export default class SyncJob {
2
- constructor();
3
- }