@leofcoin/chain 1.4.24 → 1.4.26

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 CHANGED
@@ -494,6 +494,7 @@ class Chain extends Contract {
494
494
  #participants = [];
495
495
  #participating = false;
496
496
  #jail = [];
497
+ #knownBlocks = [];
497
498
  constructor() {
498
499
  super();
499
500
  return this.#init();
@@ -589,9 +590,11 @@ class Chain extends Contract {
589
590
  promises = await Promise.allSettled(promises);
590
591
  promises = promises.filter(({ status }) => status === 'fulfilled');
591
592
  clearTimeout(timeout);
592
- promises = promises.map(({ value }) => new peernet.protos['peernet-response'](value));
593
+ promises = promises.map(async ({ value }) => {
594
+ const node = await new peernet.protos['peernet-response'](value.result);
595
+ return { value: node.decoded.response, peer: value.peer };
596
+ });
593
597
  promises = await Promise.all(promises);
594
- promises = promises.map(node => node.decoded.response);
595
598
  resolve(promises);
596
599
  });
597
600
  }
@@ -601,24 +604,40 @@ class Chain extends Contract {
601
604
  async #getLatestBlock() {
602
605
  let promises = [];
603
606
  let data = await new peernet.protos['peernet-request']({ request: 'lastBlock' });
604
- const node = await peernet.prepareMessage(data);
607
+ let node = await peernet.prepareMessage(data);
605
608
  for (const peer of peernet.connections) {
606
609
  if (peer.connected && peer.readyState === 'open' && peer.peerId !== this.id) {
607
- promises.push(peer.request(node.encoded));
610
+ promises.push(async () => {
611
+ try {
612
+ const result = await peer.request(node.encoded);
613
+ return { result, peer };
614
+ }
615
+ catch (error) {
616
+ throw error;
617
+ }
618
+ });
608
619
  }
609
620
  else if (!peer.connected || peer.readyState !== 'open') ;
610
621
  }
611
622
  promises = await this.promiseRequests(promises);
612
- let latest = { index: 0, hash: '0x0' };
613
- for (const value of promises) {
614
- if (value.index > latest.index) {
615
- latest.index = value.index;
616
- latest.hash = await value.hash();
617
- }
618
- }
623
+ let latest = { index: 0, hash: '0x0', previousHash: '0x0' };
624
+ promises = promises.sort((a, b) => b.index - a.index);
625
+ latest = promises[0].value;
619
626
  if (latest.hash && latest.hash !== '0x0') {
620
- latest = await peernet.get(latest.hash, block);
621
- latest = await new BlockMessage(latest);
627
+ let message = await peernet.get(latest.hash, 'block');
628
+ message = await new BlockMessage(message);
629
+ const hash = await message.hash();
630
+ if (hash !== latest.hash)
631
+ throw new Error('invalid block @getLatestBlock');
632
+ let data = await new peernet.protos['peernet-request']({ request: 'knownBlocks' });
633
+ let node = await peernet.prepareMessage(data);
634
+ const peer = promises[0].peer;
635
+ if (peer.connected && peer.readyState === 'open' && peer.peerId !== this.id) {
636
+ let message = await peer.request(node);
637
+ message = await new peernet.protos['peernet-response'](message);
638
+ this.#knownBlocks = message.decoded.response;
639
+ }
640
+ latest = { ...message.decoded, hash };
622
641
  }
623
642
  return latest;
624
643
  }
@@ -658,6 +677,7 @@ class Chain extends Contract {
658
677
  return new BWMessage(peernet.client.bw) || { up: 0, down: 0 };
659
678
  });
660
679
  await peernet.addRequestHandler('lastBlock', this.#lastBlockHandler.bind(this));
680
+ await peernet.addRequestHandler('knownBlocks', this.#knownBlocksHandler.bind(this));
661
681
  peernet.subscribe('add-block', this.#addBlock.bind(this));
662
682
  peernet.subscribe('add-transaction', this.#addTransaction.bind(this));
663
683
  peernet.subscribe('validator:timeout', this.#validatorTimeout.bind(this));
@@ -677,6 +697,15 @@ class Chain extends Contract {
677
697
  async #syncChain(lastBlock) {
678
698
  if (this.#chainSyncing || !lastBlock || !lastBlock.hash || !lastBlock.hash)
679
699
  return;
700
+ if (this.#knownBlocks?.length === Number(lastBlock.index) + 1) {
701
+ let promises = [];
702
+ promises = await Promise.allSettled(this.#knownBlocks.map(async (address) => {
703
+ const has = await peernet.has(address, 'block');
704
+ return { has, address };
705
+ }));
706
+ promises = promises.filter(({ status, value }) => status === 'fulfilled' && !value.has);
707
+ await Promise.allSettled(promises.map(({ value }) => peernet.get(value.address, 'block')));
708
+ }
680
709
  if (!this.lastBlock || Number(this.lastBlock.index) < Number(lastBlock.index)) {
681
710
  this.#chainSyncing = true;
682
711
  // TODO: check if valid
@@ -704,6 +733,9 @@ class Chain extends Contract {
704
733
  async #lastBlockHandler() {
705
734
  return new peernet.protos['peernet-response']({ response: { hash: this.#lastBlock?.hash, index: this.#lastBlock?.index } });
706
735
  }
736
+ async #knownBlocksHandler() {
737
+ return new peernet.protos['peernet-response']({ response: { blocks: this.#blocks.map((block) => block.hash) } });
738
+ }
707
739
  async resolveBlock(hash) {
708
740
  if (!hash)
709
741
  throw new Error(`expected hash, got: ${hash}`);
@@ -986,9 +1018,14 @@ class Chain extends Contract {
986
1018
  this.#addTransaction(event.message.encoded);
987
1019
  return event;
988
1020
  }
989
- async addContract(contractMessage) {
1021
+ async addContract(transaction, contractMessage) {
990
1022
  const hash = await contractMessage.hash();
991
- await this.staticCall(hash, 'get');
1023
+ const has = await this.staticCall(addresses.contractFactory, 'isRegistered', [hash]);
1024
+ if (has)
1025
+ throw new Error('contract exists');
1026
+ const tx = await this.sendTransaction(transaction);
1027
+ await tx.wait;
1028
+ return tx;
992
1029
  }
993
1030
  /**
994
1031
  *
@@ -23,6 +23,7 @@ export default class Chain extends Contract {
23
23
  getLatestBlock(): Promise<{
24
24
  index: number;
25
25
  hash: string;
26
+ previousHash: string;
26
27
  }>;
27
28
  resolveBlock(hash: any): any;
28
29
  resolveBlocks(): any;
@@ -39,7 +40,13 @@ export default class Chain extends Contract {
39
40
  wait: Promise<unknown>;
40
41
  message: any;
41
42
  }>;
42
- addContract(contractMessage: any): Promise<void>;
43
+ addContract(transaction: any, contractMessage: any): Promise<{
44
+ hash: any;
45
+ data: any;
46
+ fee: string | 0;
47
+ wait: Promise<unknown>;
48
+ message: any;
49
+ }>;
43
50
  /**
44
51
  *
45
52
  * @param {Address} sender
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leofcoin/chain",
3
- "version": "1.4.24",
3
+ "version": "1.4.26",
4
4
  "description": "Official javascript implementation",
5
5
  "exports": {
6
6
  "./node": "./exports/node.js",