@leofcoin/chain 1.5.24 → 1.5.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.
@@ -1,4 +1,4 @@
1
- import { B as BigNumber, L as Logger, v as version$1, h as hexZeroPad, i as isBigNumberish, a as arrayify, b as isBytes, T as TransactionMessage, t as toBase58, C as ContractMessage, R as RawTransactionMessage, c as BlockMessage, d as BWMessage, e as BWRequestMessage } from './index-de7cd283.js';
1
+ import { B as BigNumber, L as Logger, v as version$1, h as hexZeroPad, i as isBigNumberish, a as arrayify, b as isBytes, T as TransactionMessage, t as toBase58, C as ContractMessage, R as RawTransactionMessage, c as BlockMessage, d as BWMessage, e as BWRequestMessage } from './index-055d5584.js';
2
2
 
3
3
  const logger$1 = new Logger(version$1);
4
4
  const _constructorGuard = {};
@@ -410,15 +410,15 @@ var addresses$1 = {
410
410
  validators: validators$1
411
411
  };
412
412
 
413
- const contractFactory$2 = addresses$1.contractFactory;
414
- const nameService$2 = addresses$1.nameService;
415
- const nativeToken$2 = addresses$1.nativeToken;
416
- const validators$2 = addresses$1.validators;
417
- var addresses = {
418
- contractFactory: contractFactory$2,
419
- nameService: nameService$2,
420
- nativeToken: nativeToken$2,
421
- validators: validators$2
413
+ const contractFactory$2 = addresses$1.contractFactory;
414
+ const nameService$2 = addresses$1.nameService;
415
+ const nativeToken$2 = addresses$1.nativeToken;
416
+ const validators$2 = addresses$1.validators;
417
+ var addresses = {
418
+ contractFactory: contractFactory$2,
419
+ nameService: nameService$2,
420
+ nativeToken: nativeToken$2,
421
+ validators: validators$2
422
422
  };
423
423
 
424
424
  var contractFactory = "237,198,141,3,53,89,84,113,119,88,110,55,76,101,103,89,119,65,109,100,117,75,88,119,116,83,52,118,52,100,97,114,113,66,84,81,82,76,90,106,50,57,117,106,112,114,98,104,52,119,121,76,106,112,56,50,87,106,173,5,99,108,97,115,115,32,70,97,99,116,111,114,121,123,35,110,97,109,101,61,34,65,114,116,79,110,108,105,110,101,67,111,110,116,114,97,99,116,70,97,99,116,111,114,121,34,59,35,116,111,116,97,108,67,111,110,116,114,97,99,116,115,61,48,59,35,99,111,110,116,114,97,99,116,115,61,91,93,59,99,111,110,115,116,114,117,99,116,111,114,40,115,116,97,116,101,41,123,115,116,97,116,101,38,38,40,116,104,105,115,46,35,99,111,110,116,114,97,99,116,115,61,115,116,97,116,101,46,99,111,110,116,114,97,99,116,115,44,116,104,105,115,46,35,116,111,116,97,108,67,111,110,116,114,97,99,116,115,61,115,116,97,116,101,46,116,111,116,97,108,67,111,110,116,114,97,99,116,115,41,125,103,101,116,32,115,116,97,116,101,40,41,123,114,101,116,117,114,110,123,116,111,116,97,108,67,111,110,116,114,97,99,116,115,58,116,104,105,115,46,35,116,111,116,97,108,67,111,110,116,114,97,99,116,115,44,99,111,110,116,114,97,99,116,115,58,116,104,105,115,46,35,99,111,110,116,114,97,99,116,115,125,125,103,101,116,32,110,97,109,101,40,41,123,114,101,116,117,114,110,32,116,104,105,115,46,35,110,97,109,101,125,103,101,116,32,99,111,110,116,114,97,99,116,115,40,41,123,114,101,116,117,114,110,91,46,46,46,116,104,105,115,46,35,99,111,110,116,114,97,99,116,115,93,125,103,101,116,32,116,111,116,97,108,67,111,110,116,114,97,99,116,115,40,41,123,114,101,116,117,114,110,32,116,104,105,115,46,35,116,111,116,97,108,67,111,110,116,114,97,99,116,115,125,105,115,82,101,103,105,115,116,101,114,101,100,40,97,100,100,114,101,115,115,41,123,114,101,116,117,114,110,32,116,104,105,115,46,35,99,111,110,116,114,97,99,116,115,46,105,110,99,108,117,100,101,115,40,97,100,100,114,101,115,115,41,125,97,115,121,110,99,32,114,101,103,105,115,116,101,114,67,111,110,116,114,97,99,116,40,97,100,100,114,101,115,115,41,123,105,102,40,97,119,97,105,116,32,109,115,103,46,115,116,97,116,105,99,67,97,108,108,40,97,100,100,114,101,115,115,44,34,104,97,115,82,111,108,101,34,44,91,109,115,103,46,115,101,110,100,101,114,44,34,79,87,78,69,82,34,93,41,44,116,104,105,115,46,35,99,111,110,116,114,97,99,116,115,46,105,110,99,108,117,100,101,115,40,97,100,100,114,101,115,115,41,41,116,104,114,111,119,32,110,101,119,32,69,114,114,111,114,40,34,97,108,114,101,97,100,121,32,114,101,103,105,115,116,101,114,101,100,34,41,59,116,104,105,115,46,35,116,111,116,97,108,67,111,110,116,114,97,99,116,115,43,61,49,44,116,104,105,115,46,35,99,111,110,116,114,97,99,116,115,46,112,117,115,104,40,97,100,100,114,101,115,115,41,125,125,114,101,116,117,114,110,32,70,97,99,116,111,114,121,59,2,91,93";
@@ -474,7 +474,7 @@ const requestTimeout = 30000;
474
474
  const syncTimeout = 30000;
475
475
  class Protocol {
476
476
  constructor() {
477
- this.resolveTimeout = 30000;
477
+ this.resolveTimeout = 10000;
478
478
  }
479
479
  get limit() {
480
480
  return limit;
@@ -503,11 +503,11 @@ class Transaction extends Protocol {
503
503
  return new Promise(async (resolve, reject) => {
504
504
  let size = 0;
505
505
  const _transactions = [];
506
- await Promise.all(transactions
507
- .map(async (tx) => {
506
+ await Promise.all(transactions.map(async (tx) => {
508
507
  tx = await new TransactionMessage(tx);
509
508
  size += tx.encoded.length;
510
- if (!formatBytes(size).includes('MB') || formatBytes(size).includes('MB') && Number(formatBytes(size).split(' MB')[0]) <= 0.75)
509
+ if (!formatBytes(size).includes('MB') ||
510
+ (formatBytes(size).includes('MB') && Number(formatBytes(size).split(' MB')[0]) <= 0.75))
511
511
  _transactions.push({ ...tx.decoded, hash: await tx.hash() });
512
512
  else
513
513
  resolve(_transactions);
@@ -521,7 +521,7 @@ class Transaction extends Protocol {
521
521
  * @returns {TransactionMessage}
522
522
  */
523
523
  async promiseTransactions(transactions) {
524
- transactions = await Promise.all(transactions.map(tx => new TransactionMessage(tx.encoded || tx)));
524
+ transactions = await Promise.all(transactions.map((tx) => new TransactionMessage(tx.encoded || tx)));
525
525
  return transactions;
526
526
  }
527
527
  /**
@@ -530,7 +530,7 @@ class Transaction extends Protocol {
530
530
  * @returns {Object} {transaction.decoded, transaction.hash}
531
531
  */
532
532
  async promiseTransactionsContent(transactions) {
533
- transactions = await Promise.all(transactions.map(tx => new Promise(async (resolve, reject) => {
533
+ transactions = await Promise.all(transactions.map((tx) => new Promise(async (resolve, reject) => {
534
534
  resolve({ ...tx.decoded, hash: await tx.hash() });
535
535
  })));
536
536
  return transactions;
@@ -543,7 +543,7 @@ class Transaction extends Protocol {
543
543
  async #getNonceFallback(address) {
544
544
  let transactions = await globalThis.transactionPoolStore.values();
545
545
  transactions = await this.promiseTransactions(transactions);
546
- transactions = transactions.filter(tx => tx.decoded.from === address);
546
+ transactions = transactions.filter((tx) => tx.decoded.from === address);
547
547
  transactions = await this.promiseTransactionsContent(transactions);
548
548
  // @ts-ignore
549
549
  if (this.lastBlock?.hash && transactions.length === 0 && this.lastBlock.hash !== '0x0') {
@@ -554,11 +554,11 @@ class Transaction extends Protocol {
554
554
  // tx = await peernet.get(tx, 'transaction')
555
555
  // transactions.push(new TransactionMessage(tx))
556
556
  // }
557
- transactions = transactions.filter(tx => tx.from === address);
557
+ transactions = transactions.filter((tx) => tx.from === address);
558
558
  while (transactions.length === 0 && block.decoded.index !== 0 && block.decoded.previousHash !== '0x0') {
559
559
  block = await globalThis.blockStore.get(block.decoded.previousHash);
560
560
  block = await new BlockMessage(block);
561
- transactions = block.decoded.transactions.filter(tx => tx.from === address);
561
+ transactions = block.decoded.transactions.filter((tx) => tx.from === address);
562
562
  }
563
563
  }
564
564
  if (transactions.length === 0)
@@ -572,7 +572,7 @@ class Transaction extends Protocol {
572
572
  * @returns {Number} nonce
573
573
  */
574
574
  async getNonce(address) {
575
- if (!await globalThis.accountsStore.has(address)) {
575
+ if (!(await globalThis.accountsStore.has(address))) {
576
576
  const nonce = await this.#getNonceFallback(address);
577
577
  await globalThis.accountsStore.put(address, new TextEncoder().encode(String(nonce)));
578
578
  }
@@ -581,7 +581,7 @@ class Transaction extends Protocol {
581
581
  nonce = new TextDecoder().decode(nonce);
582
582
  let transactions = await globalThis.transactionPoolStore.values();
583
583
  transactions = await this.promiseTransactions(transactions);
584
- transactions = transactions.filter(tx => tx.decoded.from === address);
584
+ transactions = transactions.filter((tx) => tx.decoded.from === address);
585
585
  transactions = await this.promiseTransactionsContent(transactions);
586
586
  for (const transaction of transactions) {
587
587
  if (transaction.nonce > nonce)
@@ -598,7 +598,7 @@ class Transaction extends Protocol {
598
598
  throw new Error(`a transaction with the same nonce already exists`);
599
599
  let transactions = await globalThis.transactionPoolStore.values();
600
600
  transactions = await this.promiseTransactions(transactions);
601
- transactions = transactions.filter(tx => tx.decoded.from === address);
601
+ transactions = transactions.filter((tx) => tx.decoded.from === address);
602
602
  for (const transaction of transactions) {
603
603
  if (transaction.decoded.nonce > nonce)
604
604
  throw new Error(`a transaction with a higher nonce already exists`);
@@ -677,8 +677,7 @@ class Contract extends Transaction {
677
677
  constructor() {
678
678
  super();
679
679
  }
680
- async init() {
681
- }
680
+ async init() { }
682
681
  /**
683
682
  *
684
683
  * @param {Address} creator
@@ -728,7 +727,7 @@ class Contract extends Transaction {
728
727
  }
729
728
  }
730
729
 
731
- const randombytes = strength => crypto.getRandomValues(new Uint8Array(strength));
730
+ const randombytes = (strength) => crypto.getRandomValues(new Uint8Array(strength));
732
731
 
733
732
  class EasyWorker {
734
733
  #messageEvent = 'message'
@@ -899,7 +898,10 @@ class Machine {
899
898
  // browser env
900
899
  pre = './';
901
900
  }
902
- this.worker = await new EasyWorker(pre + 'workers/machine-worker.js', { serialization: 'advanced', type: 'module' });
901
+ this.worker = await new EasyWorker(pre + 'workers/machine-worker.js', {
902
+ serialization: 'advanced',
903
+ type: 'module'
904
+ });
903
905
  this.worker.onmessage(this.#onmessage.bind(this));
904
906
  // const blocks = await blockStore.values()
905
907
  const contracts = await Promise.all([
@@ -925,7 +927,7 @@ class Machine {
925
927
  return new Promise((resolve, reject) => {
926
928
  // @ts-ignore
927
929
  const id = randombytes(20).toString('hex');
928
- const onmessage = message => {
930
+ const onmessage = (message) => {
929
931
  pubsub.unsubscribe(id, onmessage);
930
932
  if (message?.error)
931
933
  reject(message.error);
@@ -957,7 +959,7 @@ class Machine {
957
959
  if (await this.has(parameters[0]))
958
960
  throw new Error(`duplicate contract @${parameters[0]}`);
959
961
  let message;
960
- if (!await globalThis.contractStore.has(parameters[0])) {
962
+ if (!(await globalThis.contractStore.has(parameters[0]))) {
961
963
  message = await peernet.get(parameters[0], 'contract');
962
964
  message = await new ContractMessage(message);
963
965
  await globalThis.contractStore.put(await message.hash(), message.encoded);
@@ -966,7 +968,7 @@ class Machine {
966
968
  message = await globalThis.contractStore.get(parameters[0]);
967
969
  message = await new ContractMessage(message);
968
970
  }
969
- if (!await this.has(await message.hash()))
971
+ if (!(await this.has(await message.hash())))
970
972
  await this.#runContract(message);
971
973
  }
972
974
  }
@@ -976,7 +978,7 @@ class Machine {
976
978
  return new Promise((resolve, reject) => {
977
979
  // @ts-ignore
978
980
  const id = randombytes(20).toString('hex');
979
- const onmessage = message => {
981
+ const onmessage = (message) => {
980
982
  pubsub.unsubscribe(id, onmessage);
981
983
  if (message?.error)
982
984
  reject(new ExecutionError(message.error));
@@ -998,7 +1000,7 @@ class Machine {
998
1000
  get(contract, method, parameters) {
999
1001
  return new Promise((resolve, reject) => {
1000
1002
  const id = randombytes(20).toString();
1001
- const onmessage = message => {
1003
+ const onmessage = (message) => {
1002
1004
  pubsub.unsubscribe(id, onmessage);
1003
1005
  resolve(message);
1004
1006
  };
@@ -1018,7 +1020,7 @@ class Machine {
1018
1020
  return new Promise((resolve, reject) => {
1019
1021
  // @ts-ignore
1020
1022
  const id = randombytes(20).toString('hex');
1021
- const onmessage = message => {
1023
+ const onmessage = (message) => {
1022
1024
  pubsub.unsubscribe(id, onmessage);
1023
1025
  if (message?.error)
1024
1026
  reject(message.error);
@@ -1044,7 +1046,7 @@ class Machine {
1044
1046
  */
1045
1047
  async deleteAll() {
1046
1048
  let hashes = await globalThis.contractStore.keys();
1047
- hashes = Object.keys(hashes).map(hash => this.delete(hash));
1049
+ hashes = Object.keys(hashes).map((hash) => this.delete(hash));
1048
1050
  return Promise.all(hashes);
1049
1051
  }
1050
1052
  }
@@ -1060,7 +1062,7 @@ class Jobber {
1060
1062
  const timeout = setTimeout(() => {
1061
1063
  reject('timeout');
1062
1064
  }, this.timeout);
1063
- this.stop = () => {
1065
+ this.destroy = () => {
1064
1066
  clearTimeout(timeout);
1065
1067
  this.busy = false;
1066
1068
  resolve('stopped');
@@ -1072,6 +1074,7 @@ class Jobber {
1072
1074
  resolve(result);
1073
1075
  }
1074
1076
  catch (error) {
1077
+ clearTimeout(timeout);
1075
1078
  reject(error);
1076
1079
  }
1077
1080
  });
@@ -1085,6 +1088,7 @@ class State extends Contract {
1085
1088
  #resolving;
1086
1089
  #resolveErrorCount;
1087
1090
  #syncState;
1091
+ #chainState;
1088
1092
  #lastBlockInQue;
1089
1093
  #syncErrorCount;
1090
1094
  #blockHashMap;
@@ -1094,6 +1098,12 @@ class State extends Contract {
1094
1098
  #totalSize;
1095
1099
  #machine;
1096
1100
  #loaded;
1101
+ get state() {
1102
+ return {
1103
+ sync: this.#syncState,
1104
+ chain: this.#chainState
1105
+ };
1106
+ }
1097
1107
  get blockHashMap() {
1098
1108
  return this.#blockHashMap.entries();
1099
1109
  }
@@ -1155,8 +1165,10 @@ class State extends Contract {
1155
1165
  }
1156
1166
  constructor() {
1157
1167
  super();
1168
+ this.#lastResolvedTime = 0;
1158
1169
  this.#resolving = false;
1159
1170
  this.#resolveErrorCount = 0;
1171
+ this.#chainState = 'loading';
1160
1172
  this.#syncErrorCount = 0;
1161
1173
  this.#blockHashMap = new Map();
1162
1174
  this.#chainSyncing = false;
@@ -1188,12 +1200,28 @@ class State extends Contract {
1188
1200
  * {Number}
1189
1201
  */
1190
1202
  this.#totalTransactions = 0;
1203
+ this.#chainStateHandler = () => {
1204
+ return new globalThis.peernet.protos['peernet-response']({
1205
+ response: this.#chainState
1206
+ });
1207
+ };
1208
+ this.#lastBlockHandler = async () => {
1209
+ return new globalThis.peernet.protos['peernet-response']({
1210
+ response: { hash: this.#lastBlock?.hash, index: this.#lastBlock?.index }
1211
+ });
1212
+ };
1213
+ this.#knownBlocksHandler = async () => {
1214
+ return new globalThis.peernet.protos['peernet-response']({
1215
+ response: { blocks: this.#blocks.map((block) => block.hash) }
1216
+ });
1217
+ };
1191
1218
  this.#loadBlockTransactions = (transactions) => Promise.all(transactions.map((transaction) => new TransactionMessage(transaction)));
1192
1219
  this.#getLastTransactions = async () => {
1193
- let lastTransactions = (await Promise.all(this.#blocks.filter(block => block.loaded).slice(-128)
1194
- .map(block => this.#loadBlockTransactions(block.transactions))))
1195
- .reduce((all, transactions) => [...all, ...transactions], []);
1196
- return Promise.all(lastTransactions.map(transaction => transaction.hash()));
1220
+ let lastTransactions = (await Promise.all(this.#blocks
1221
+ .filter((block) => block.loaded)
1222
+ .slice(-128)
1223
+ .map((block) => this.#loadBlockTransactions(block.transactions)))).reduce((all, transactions) => [...all, ...transactions], []);
1224
+ return Promise.all(lastTransactions.map((transaction) => transaction.hash()));
1197
1225
  };
1198
1226
  }
1199
1227
  async clearPool() {
@@ -1208,12 +1236,16 @@ class State extends Contract {
1208
1236
  await globalThis.blockStore.clear();
1209
1237
  await globalThis.transactionPoolStore.clear();
1210
1238
  }
1239
+ #chainStateHandler;
1240
+ #lastBlockHandler;
1241
+ #knownBlocksHandler;
1211
1242
  async init() {
1212
- this.jobber = new Jobber(30000);
1243
+ this.jobber = new Jobber(this.resolveTimeout);
1213
1244
  if (super.init)
1214
1245
  await super.init();
1215
- await globalThis.peernet.addRequestHandler('lastBlock', this.#lastBlockHandler.bind(this));
1216
- await globalThis.peernet.addRequestHandler('knownBlocks', this.#knownBlocksHandler.bind(this));
1246
+ await globalThis.peernet.addRequestHandler('lastBlock', this.#lastBlockHandler);
1247
+ await globalThis.peernet.addRequestHandler('knownBlocks', this.#knownBlocksHandler);
1248
+ await globalThis.peernet.addRequestHandler('chainState', this.#chainStateHandler);
1217
1249
  try {
1218
1250
  let localBlock;
1219
1251
  try {
@@ -1227,7 +1259,10 @@ class State extends Contract {
1227
1259
  if (localBlock && localBlock !== '0x0') {
1228
1260
  localBlock = await globalThis.peernet.get(localBlock, 'block');
1229
1261
  localBlock = await new BlockMessage(localBlock);
1230
- this.#lastBlock = { ...localBlock.decoded, hash: await localBlock.hash() };
1262
+ this.#lastBlock = {
1263
+ ...localBlock.decoded,
1264
+ hash: await localBlock.hash()
1265
+ };
1231
1266
  }
1232
1267
  else {
1233
1268
  if (globalThis.peernet?.connections.length > 0) {
@@ -1268,12 +1303,6 @@ class State extends Contract {
1268
1303
  await globalThis.chainStore.put('lastBlock', hash);
1269
1304
  globalThis.pubsub.publish('lastBlock', this.#lastBlock);
1270
1305
  }
1271
- async #lastBlockHandler() {
1272
- return new globalThis.peernet.protos['peernet-response']({ response: { hash: this.#lastBlock?.hash, index: this.#lastBlock?.index } });
1273
- }
1274
- async #knownBlocksHandler() {
1275
- return new globalThis.peernet.protos['peernet-response']({ response: { blocks: this.#blocks.map((block) => block.hash) } });
1276
- }
1277
1306
  getLatestBlock() {
1278
1307
  // @ts-ignore
1279
1308
  return this.#getLatestBlock();
@@ -1286,7 +1315,7 @@ class State extends Contract {
1286
1315
  const { index } = block.decoded;
1287
1316
  if (this.#blocks[index - 1] && this.#blocks[index - 1].hash !== block.hash)
1288
1317
  throw `invalid block ${hash} @${index}`;
1289
- if (!await globalThis.peernet.has(hash))
1318
+ if (!(await globalThis.peernet.has(hash)))
1290
1319
  await globalThis.peernet.put(hash, block.encoded, 'block');
1291
1320
  }
1292
1321
  return block;
@@ -1314,8 +1343,6 @@ class State extends Contract {
1314
1343
  this.#lastResolvedTime = Date.now();
1315
1344
  }
1316
1345
  catch (error) {
1317
- this.#resolving = false;
1318
- this.#chainSyncing = false;
1319
1346
  throw new ResolveError(`block: ${hash}@${index}`);
1320
1347
  }
1321
1348
  return;
@@ -1328,6 +1355,8 @@ class State extends Contract {
1328
1355
  if (this.#resolving)
1329
1356
  return 'already resolving';
1330
1357
  this.#resolving = true;
1358
+ if (this.jobber.busy && this.jobber.destroy)
1359
+ await this.jobber.destroy();
1331
1360
  try {
1332
1361
  await this.jobber.add(() => this.#resolveBlock(hash));
1333
1362
  this.#resolving = false;
@@ -1337,6 +1366,7 @@ class State extends Contract {
1337
1366
  catch (error) {
1338
1367
  console.log({ error });
1339
1368
  this.#resolveErrorCount += 1;
1369
+ this.#resolving = false;
1340
1370
  if (this.#resolveErrorCount < 3)
1341
1371
  return this.resolveBlock(hash);
1342
1372
  this.#resolveErrorCount = 0;
@@ -1345,8 +1375,8 @@ class State extends Contract {
1345
1375
  }
1346
1376
  async resolveBlocks() {
1347
1377
  try {
1348
- if (this.jobber.busy && this.jobber.stop) {
1349
- await this.jobber.stop();
1378
+ if (this.jobber.busy && this.jobber.destroy) {
1379
+ await this.jobber.destroy();
1350
1380
  }
1351
1381
  }
1352
1382
  catch (error) {
@@ -1362,10 +1392,10 @@ class State extends Contract {
1362
1392
  }
1363
1393
  catch (error) {
1364
1394
  console.log(error);
1395
+ this.#chainSyncing = false;
1396
+ this.#syncState = 'errored';
1365
1397
  this.#resolveErrored = true;
1366
- this.#resolveErrorCount += 1;
1367
- this.#resolving = false;
1368
- this.restoreChain();
1398
+ return this.restoreChain();
1369
1399
  // console.log(e);
1370
1400
  }
1371
1401
  }
@@ -1383,23 +1413,24 @@ class State extends Contract {
1383
1413
  this.#resolveErrored = true;
1384
1414
  this.#resolveErrorCount += 1;
1385
1415
  this.#resolving = false;
1386
- this.restoreChain();
1416
+ return this.restoreChain();
1387
1417
  // console.log(e);
1388
1418
  }
1389
1419
  }
1420
+ destroyResolveJob() { }
1390
1421
  async syncChain(lastBlock) {
1391
- if (!this.shouldSync) {
1422
+ if (!this.shouldSync)
1392
1423
  return;
1393
- }
1424
+ this.#syncState;
1425
+ this.#chainSyncing = true;
1394
1426
  try {
1395
- if (this.jobber.busy && this.jobber.stop) {
1396
- await this.jobber.stop();
1427
+ if (this.jobber.busy && this.jobber.destroy) {
1428
+ await this.jobber.destroy();
1397
1429
  }
1398
1430
  }
1399
1431
  catch (error) {
1400
1432
  console.error(error);
1401
1433
  }
1402
- this.#chainSyncing = true;
1403
1434
  if (!lastBlock)
1404
1435
  lastBlock = await this.#getLatestBlock();
1405
1436
  console.log('starting sync');
@@ -1414,7 +1445,8 @@ class State extends Contract {
1414
1445
  return this.syncChain(lastBlock);
1415
1446
  this.#syncErrorCount = 0;
1416
1447
  this.#chainSyncing = false;
1417
- return 'errored';
1448
+ this.#syncState = 'errored';
1449
+ return this.#syncState;
1418
1450
  }
1419
1451
  if (lastBlock.index === this.#lastBlockInQue?.index)
1420
1452
  this.#lastBlockInQue = undefined;
@@ -1422,7 +1454,8 @@ class State extends Contract {
1422
1454
  this.#chainSyncing = false;
1423
1455
  if (this.#lastBlockInQue)
1424
1456
  return this.syncChain(this.#lastBlockInQue);
1425
- return 'synced';
1457
+ this.#syncState = 'synced';
1458
+ return this.#syncState;
1426
1459
  }
1427
1460
  async #syncChain(lastBlock) {
1428
1461
  try {
@@ -1443,7 +1476,7 @@ class State extends Contract {
1443
1476
  console.log('ok');
1444
1477
  let blocksSynced = localIndex > 0 ? (localIndex > index ? localIndex - index : index + -localIndex) : index;
1445
1478
  globalThis.debug(`synced ${blocksSynced} ${blocksSynced > 1 ? 'blocks' : 'block'}`);
1446
- const start = (this.#blocks.length - blocksSynced);
1479
+ const start = this.#blocks.length - blocksSynced;
1447
1480
  if (this.#machine)
1448
1481
  await this.#loadBlocks(this.blocks.slice(start));
1449
1482
  await this.updateState(new BlockMessage(this.#blocks[this.#blocks.length - 1]));
@@ -1456,7 +1489,9 @@ class State extends Contract {
1456
1489
  }
1457
1490
  async #getLatestBlock() {
1458
1491
  let promises = [];
1459
- let data = await new globalThis.peernet.protos['peernet-request']({ request: 'lastBlock' });
1492
+ let data = await new globalThis.peernet.protos['peernet-request']({
1493
+ request: 'lastBlock'
1494
+ });
1460
1495
  let node = await globalThis.peernet.prepareMessage(data);
1461
1496
  for (const peer of globalThis.peernet?.connections) {
1462
1497
  // @ts-ignore
@@ -1488,7 +1523,9 @@ class State extends Contract {
1488
1523
  latest = { ...message.decoded, hash };
1489
1524
  const peer = promises[0].peer;
1490
1525
  if (peer.connected && peer.version === this.version) {
1491
- let data = await new globalThis.peernet.protos['peernet-request']({ request: 'knownBlocks' });
1526
+ let data = await new globalThis.peernet.protos['peernet-request']({
1527
+ request: 'knownBlocks'
1528
+ });
1492
1529
  let node = await globalThis.peernet.prepareMessage(data);
1493
1530
  let message = await peer.request(node);
1494
1531
  message = await new globalThis.peernet.protos['peernet-response'](message);
@@ -1504,6 +1541,7 @@ class State extends Contract {
1504
1541
  * @param {Block[]} blocks
1505
1542
  */
1506
1543
  async #loadBlocks(blocks) {
1544
+ this.#chainState = 'loading';
1507
1545
  let poolTransactionKeys = await globalThis.transactionPoolStore.keys();
1508
1546
  for (const block of blocks) {
1509
1547
  if (block && !block.loaded) {
@@ -1556,6 +1594,7 @@ class State extends Contract {
1556
1594
  globalThis.pubsub.publish('block-loaded', { ...block });
1557
1595
  }
1558
1596
  }
1597
+ this.#chainState = 'loaded';
1559
1598
  return true;
1560
1599
  }
1561
1600
  promiseRequests(promises) {
@@ -1586,9 +1625,12 @@ class State extends Contract {
1586
1625
  return true;
1587
1626
  }
1588
1627
  get shouldSync() {
1589
- if (this.canSync ||
1590
- this.#resolveErrored ||
1591
- !this.canSync && this.#lastResolvedTime + this.resolveTimeout > new Date().getTime())
1628
+ if (this.#chainSyncing)
1629
+ return false;
1630
+ if (this.#resolveErrored ||
1631
+ this.#syncState === 'errored' ||
1632
+ this.#syncState === 'connectionless' ||
1633
+ (!this.canSync && this.#lastResolvedTime + this.resolveTimeout > Date.now()))
1592
1634
  return true;
1593
1635
  return false;
1594
1636
  }
@@ -1608,7 +1650,7 @@ class VersionControl extends State {
1608
1650
  super();
1609
1651
  }
1610
1652
  async init() {
1611
- super.init && await super.init();
1653
+ super.init && (await super.init());
1612
1654
  console.log('init');
1613
1655
  try {
1614
1656
  const version = await globalThis.chainStore.get('version');
@@ -1690,29 +1732,34 @@ class Chain extends VersionControl {
1690
1732
  console.error(error);
1691
1733
  }
1692
1734
  const end = Date.now();
1693
- console.log(((end - start) / 1000) + ' s');
1735
+ console.log((end - start) / 1000 + ' s');
1694
1736
  if (await this.hasTransactionToHandle())
1695
1737
  return this.#runEpoch();
1696
1738
  this.#runningEpoch = false;
1697
1739
  // if (await this.hasTransactionToHandle() && !this.#runningEpoch) return this.#runEpoch()
1698
1740
  }
1699
1741
  async #setup() {
1700
- const contracts = [{
1742
+ const contracts = [
1743
+ {
1701
1744
  address: addresses.contractFactory,
1702
1745
  message: contractFactoryMessage
1703
- }, {
1746
+ },
1747
+ {
1704
1748
  address: addresses.nativeToken,
1705
1749
  message: nativeTokenMessage
1706
- }, {
1750
+ },
1751
+ {
1707
1752
  address: addresses.validators,
1708
1753
  message: validatorsMessage
1709
- }, {
1754
+ },
1755
+ {
1710
1756
  address: addresses.nameService,
1711
1757
  message: nameServiceMessage
1712
- }];
1758
+ }
1759
+ ];
1713
1760
  await Promise.all(contracts.map(async ({ address, message }) => {
1714
1761
  // @ts-ignore
1715
- message = await new ContractMessage(Uint8Array.from(message.split(',').map(string => Number(string))));
1762
+ message = await new ContractMessage(Uint8Array.from(message.split(',').map((string) => Number(string))));
1716
1763
  // @ts-ignore
1717
1764
  await globalThis.contractStore.put(address, message.encoded);
1718
1765
  }));
@@ -1734,7 +1781,7 @@ class Chain extends VersionControl {
1734
1781
  return new BWMessage(globalThis.peernet.client.bw) || { up: 0, down: 0 };
1735
1782
  });
1736
1783
  // await globalThis.peernet.addRequestHandler('peerId', () => {
1737
- // let node =
1784
+ // let node =
1738
1785
  // globalThis.peernet.protos['peernet-response']({response: node.encoded})
1739
1786
  // })
1740
1787
  await globalThis.peernet.addRequestHandler('transactionPool', this.#transactionPoolHandler.bind(this));
@@ -1771,31 +1818,36 @@ class Chain extends VersionControl {
1771
1818
  response = await new globalThis.peernet.protos['peernet-response'](new Uint8Array(Object.values(response)));
1772
1819
  return response.decoded.response;
1773
1820
  }
1821
+ async getPeerTransactionPool(peer) {
1822
+ const transactionsInPool = await this.#makeRequest(peer, 'transactionPool');
1823
+ // todo iterate vs getting all keys?
1824
+ const transactions = await globalThis.transactionPoolStore.keys();
1825
+ const transactionsToGet = [];
1826
+ for (const key of transactionsInPool) {
1827
+ !transactions.includes(key) &&
1828
+ !ignorelist.includes(key) &&
1829
+ transactionsToGet.push(transactionPoolStore.put(key, await peernet.get(key, 'transaction')));
1830
+ }
1831
+ return Promise.all(transactionsToGet);
1832
+ }
1774
1833
  async #peerConnected(peer) {
1775
1834
  // todo handle version changes
1776
1835
  // for now just do nothing if version doesn't match
1777
1836
  if (!peer.version || peer.version !== this.version)
1778
1837
  return;
1779
1838
  const lastBlock = await this.#makeRequest(peer, 'lastBlock');
1780
- let transactionsInPool = await this.#makeRequest(peer, 'transactionPool');
1781
- const transactions = await globalThis.transactionPoolStore.keys();
1782
- const transactionsToGet = [];
1783
- for (const key of transactionsInPool) {
1784
- if (!transactions.includes(key) && !ignorelist.includes(key))
1785
- transactionsToGet.push(transactionPoolStore.put(key, (await peernet.get(key, 'transaction'))));
1786
- }
1787
- await Promise.all(transactionsToGet);
1839
+ const higherThenCurrentLocal = lastBlock.index > this.lastBlock?.index;
1840
+ const peerTransactionPool = (higherThenCurrentLocal && (await this.getPeerTransactionPool(peer))) || [];
1788
1841
  if (Object.keys(lastBlock).length > 0) {
1789
- if (!this.lastBlock || !this.blocks[this.blocks.length - 1]?.loaded || lastBlock && lastBlock.index > this.lastBlock?.index || !this.loaded && !this.resolving) {
1842
+ if (!this.lastBlock || higherThenCurrentLocal) {
1790
1843
  this.knownBlocks = await this.#makeRequest(peer, 'knownBlocks');
1791
1844
  await this.syncChain(lastBlock);
1792
- // if (await this.hasTransactionToHandle() && this.#participating) this.#runEpoch()
1793
1845
  }
1794
1846
  else if (!this.knownBlocks)
1795
1847
  this.knownBlocks = await this.#makeRequest(peer, 'knownBlocks');
1796
1848
  }
1797
- if (this.#participating)
1798
- this.#runEpoch();
1849
+ if (this.#participating && peerTransactionPool.length > 0)
1850
+ return this.#runEpoch();
1799
1851
  }
1800
1852
  #epochTimeout;
1801
1853
  async #transactionPoolHandler() {
@@ -1874,7 +1926,7 @@ class Chain extends VersionControl {
1874
1926
  // peerReputation(peerId)
1875
1927
  // {bandwith: {up, down}, uptime}
1876
1928
  this.#participating = true;
1877
- if (!await this.staticCall(addresses.validators, 'has', [address])) {
1929
+ if (!(await this.staticCall(addresses.validators, 'has', [address]))) {
1878
1930
  const rawTransaction = {
1879
1931
  from: address,
1880
1932
  to: addresses.validators,
@@ -1886,13 +1938,13 @@ class Chain extends VersionControl {
1886
1938
  const transaction = await signTransaction(rawTransaction, globalThis.peernet.identity);
1887
1939
  await this.sendTransaction(transaction);
1888
1940
  }
1889
- if (await this.hasTransactionToHandle() && !this.#runningEpoch && this.#participating)
1941
+ if ((await this.hasTransactionToHandle()) && !this.#runningEpoch && this.#participating)
1890
1942
  await this.#runEpoch();
1891
1943
  }
1892
1944
  // todo filter tx that need to wait on prev nonce
1893
1945
  async #createBlock(limit = this.transactionLimit) {
1894
1946
  // vote for transactions
1895
- if (await globalThis.transactionPoolStore.size() === 0)
1947
+ if ((await globalThis.transactionPoolStore.size()) === 0)
1896
1948
  return;
1897
1949
  let transactions = await globalThis.transactionPoolStore.values(this.transactionLimit);
1898
1950
  for (const hash of await globalThis.transactionPoolStore.keys()) {
@@ -1985,7 +2037,7 @@ class Chain extends VersionControl {
1985
2037
  }
1986
2038
  }
1987
2039
  }
1988
- block.validators = block.validators.map(validator => {
2040
+ block.validators = block.validators.map((validator) => {
1989
2041
  validator.reward = block.fees;
1990
2042
  validator.reward = validator.reward.add(block.reward);
1991
2043
  validator.reward = validator.reward.div(block.validators.length);
@@ -2003,8 +2055,7 @@ class Chain extends VersionControl {
2003
2055
  // block.reward = block.reward.toString()
2004
2056
  // block.fees = block.fees.toString()
2005
2057
  try {
2006
- block.transactions = await Promise.all(block.transactions
2007
- .map(async (transaction) => {
2058
+ block.transactions = await Promise.all(block.transactions.map(async (transaction) => {
2008
2059
  await globalThis.transactionPoolStore.delete(await transaction.hash());
2009
2060
  return transaction.decoded;
2010
2061
  }));