@leofcoin/chain 1.4.43 → 1.4.45

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, C as ContractMessage, T as TransactionMessage, c as CodecHash, d as BlockMessage, e as BWMessage, f as BWRequestMessage } from './contract-32687834.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, C as ContractMessage, T as TransactionMessage, c as CodecHash, d as BlockMessage, e as BWMessage, f as BWRequestMessage } from './contract-f76383c3.js';
2
2
 
3
3
  const logger$1 = new Logger(version$1);
4
4
  const _constructorGuard = {};
@@ -7778,7 +7778,6 @@ class Transaction extends Protocol {
7778
7778
  throw new Error(`transaction not signed`);
7779
7779
  if (message.decoded.nonce === undefined)
7780
7780
  throw new Error(`nonce required`);
7781
- message = new TransactionMessage(message.encoded);
7782
7781
  try {
7783
7782
  await this.validateNonce(message.decoded.from, message.decoded.nonce);
7784
7783
  // todo check if signature is valid
@@ -7862,6 +7861,8 @@ globalThis.BigNumber = BigNumber;
7862
7861
  // check if browser or local
7863
7862
  class Chain extends Contract {
7864
7863
  #state;
7864
+ #lastResolved;
7865
+ #slotTime = 10000;
7865
7866
  id;
7866
7867
  utils;
7867
7868
  /** {Address[]} */
@@ -8121,7 +8122,7 @@ class Chain extends Contract {
8121
8122
  return this;
8122
8123
  }
8123
8124
  async #invalidTransaction(hash) {
8124
- await transactionPoolStore.delete(hash);
8125
+ await globalThis.transactionPoolStore.delete(hash);
8125
8126
  console.log(`removed invalid transaction: ${hash}`);
8126
8127
  }
8127
8128
  async #validatorTimeout(validatorInfo) {
@@ -8138,6 +8139,19 @@ class Chain extends Contract {
8138
8139
  return 'synced';
8139
8140
  }
8140
8141
  async #syncChain(lastBlock) {
8142
+ let current;
8143
+ const timeout = () => current = setTimeout(() => {
8144
+ if (this.#chainSyncing) {
8145
+ if (this.#lastResolved + 10000 > Date.now())
8146
+ timeout();
8147
+ else {
8148
+ this.#chainSyncing = false;
8149
+ console.log('resyncing');
8150
+ this.#syncChain(lastBlock);
8151
+ }
8152
+ }
8153
+ }, 10000);
8154
+ timeout();
8141
8155
  if (this.#chainSyncing || !lastBlock || !lastBlock.hash || !lastBlock.hash)
8142
8156
  return;
8143
8157
  this.#chainSyncing = true;
@@ -8162,6 +8176,7 @@ class Chain extends Contract {
8162
8176
  await this.#loadBlocks(this.blocks.slice(start));
8163
8177
  await this.#updateState(new BlockMessage(this.#blocks[this.#blocks.length - 1]));
8164
8178
  }
8179
+ clearTimeout(current);
8165
8180
  this.#chainSyncing = false;
8166
8181
  }
8167
8182
  async #prepareRequest(request) {
@@ -8237,6 +8252,7 @@ class Chain extends Contract {
8237
8252
  this.#blocks[index] = { hash, ...block.decoded };
8238
8253
  this.#blockHashMap.set(hash, index);
8239
8254
  console.log(`resolved block: ${hash} @${index} ${formatBytes(size)}`);
8255
+ this.#lastResolved = Date.now();
8240
8256
  if (previousHash !== '0x0') {
8241
8257
  return this.resolveBlock(previousHash);
8242
8258
  }
@@ -8264,9 +8280,12 @@ class Chain extends Contract {
8264
8280
  * @param {Block[]} blocks
8265
8281
  */
8266
8282
  async #loadBlocks(blocks) {
8283
+ let poolTransactionKeys = await globalThis.transactionPoolStore.keys();
8267
8284
  for (const block of blocks) {
8268
8285
  if (block && !block.loaded) {
8269
8286
  for (const transaction of block.transactions) {
8287
+ if (poolTransactionKeys.includes(transaction.hash))
8288
+ await globalThis.transactionPoolStore.delete(transaction.hash);
8270
8289
  try {
8271
8290
  await this.#machine.execute(transaction.to, transaction.method, transaction.params);
8272
8291
  if (transaction.to === nativeToken$1) {
@@ -8380,11 +8399,12 @@ class Chain extends Contract {
8380
8399
  if (Object.keys(transactions)?.length === 0)
8381
8400
  return;
8382
8401
  const keys = await globalThis.transactionPoolStore.keys();
8402
+ const timestamp = Date.now();
8383
8403
  let block = {
8384
8404
  transactions: [],
8385
8405
  validators: [],
8386
8406
  fees: BigNumber.from(0),
8387
- timestamp: Date.now(),
8407
+ timestamp,
8388
8408
  previousHash: '',
8389
8409
  reward: parseUnits('150'),
8390
8410
  index: 0
@@ -8394,18 +8414,27 @@ class Chain extends Contract {
8394
8414
  transactions = transactions.sort((a, b) => a.nonce - b.nonce);
8395
8415
  for (let transaction of transactions) {
8396
8416
  const hash = await transaction.hash();
8397
- try {
8398
- const result = await this.#executeTransaction({ ...transaction.decoded, hash });
8399
- console.log({ result });
8400
- block.transactions.push({ hash, ...transaction.decoded });
8401
- block.fees = block.fees.add(await calculateFee(transaction.decoded));
8402
- await globalThis.accountsStore.put(transaction.decoded.from, new TextEncoder().encode(String(transaction.decoded.nonce)));
8403
- }
8404
- catch (e) {
8405
- console.log(keys.includes(hash));
8406
- console.log({ e });
8407
- console.log(hash);
8417
+ const doubleTransaction = this.#blocks.filter(({ transaction }) => transaction.hash === hash);
8418
+ if (doubleTransaction.length > 0) {
8408
8419
  await globalThis.transactionPoolStore.delete(hash);
8420
+ await globalThis.peernet.publish('invalid-transaction', hash);
8421
+ }
8422
+ else {
8423
+ if (timestamp + this.#slotTime > Date.now()) {
8424
+ try {
8425
+ const result = await this.#executeTransaction({ ...transaction.decoded, hash });
8426
+ console.log({ result });
8427
+ block.transactions.push({ hash, ...transaction.decoded });
8428
+ block.fees = block.fees.add(await calculateFee(transaction.decoded));
8429
+ await globalThis.accountsStore.put(transaction.decoded.from, new TextEncoder().encode(String(transaction.decoded.nonce)));
8430
+ }
8431
+ catch (e) {
8432
+ console.log(keys.includes(hash));
8433
+ console.log({ e });
8434
+ console.log(hash);
8435
+ await globalThis.transactionPoolStore.delete(hash);
8436
+ }
8437
+ }
8409
8438
  }
8410
8439
  }
8411
8440
  console.log(block.transactions);
@@ -8473,7 +8502,6 @@ class Chain extends Contract {
8473
8502
  await Promise.all(block.transactions
8474
8503
  .map(async (transaction) => globalThis.transactionPoolStore.delete(transaction.hash)));
8475
8504
  let blockMessage = await new BlockMessage(block);
8476
- blockMessage = await new BlockMessage(blockMessage.encoded);
8477
8505
  const hash = await blockMessage.hash();
8478
8506
  await globalThis.peernet.put(hash, blockMessage.encoded, 'block');
8479
8507
  await this.#updateState(blockMessage);
@@ -8488,18 +8516,21 @@ class Chain extends Contract {
8488
8516
  // transactionStore.put(message.hash, message.encoded)
8489
8517
  }
8490
8518
  async #addTransaction(transaction) {
8519
+ transaction = await new TransactionMessage(transaction);
8520
+ const hash = await transaction.hash();
8491
8521
  try {
8492
- transaction = await new TransactionMessage(transaction);
8493
- transaction = await new TransactionMessage(transaction.encoded);
8494
- const hash = await transaction.hash();
8495
8522
  const has = await globalThis.transactionPoolStore.has(hash);
8496
- if (!has)
8523
+ if (!has) {
8497
8524
  await globalThis.transactionPoolStore.put(hash, transaction.encoded);
8498
- if (this.#participating && !this.#runningEpoch)
8499
- this.#runEpoch();
8525
+ if (this.#participating && !this.#runningEpoch)
8526
+ this.#runEpoch();
8527
+ }
8528
+ else
8529
+ globalThis.peernet.publish('invalid-transaction', hash);
8500
8530
  }
8501
8531
  catch (e) {
8502
8532
  console.log(e);
8533
+ globalThis.peernet.publish('invalid-transaction', hash);
8503
8534
  throw new Error('invalid transaction');
8504
8535
  }
8505
8536
  }
@@ -1,5 +1,5 @@
1
- import { c as commonjsGlobal, g as getDefaultExportFromCjs } from './node-browser-35d521b9.js';
2
- import './contract-32687834.js';
1
+ import { c as commonjsGlobal, g as getDefaultExportFromCjs } from './node-browser-aa07a41d.js';
2
+ import './contract-f76383c3.js';
3
3
 
4
4
  function commonjsRequire(path) {
5
5
  throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.');
@@ -4799,12 +4799,13 @@ const isUint8Array = (type) => type === 'uint8Array';
4799
4799
  const isBigNumber = (type) => type === 'bigNumber';
4800
4800
  const tokenize = (key, value) => {
4801
4801
  const optional = key.endsWith('?');
4802
- let type = value;
4803
- type = Array.isArray(type) ? 'array' : typeof type;
4804
- if (value instanceof Uint8Array)
4802
+ let type = value === undefined ? key : value;
4803
+ if (type instanceof Uint8Array)
4805
4804
  type = 'uint8Array';
4806
- else if (value._isBigNumber)
4805
+ else if (type?._isBigNumber || type.isBigNumber)
4807
4806
  type = 'bigNumber';
4807
+ else
4808
+ type = Array.isArray(type) ? 'array' : typeof type;
4808
4809
  const parts = key.split('?');
4809
4810
  const minimumLength = parts[2]?.includes('min') ? parts[2].split['min:'][1] : 0;
4810
4811
  return { type, optional, key: parts[0], minimumLength };
@@ -4816,6 +4817,7 @@ const toType = (data) => {
4816
4817
  // returns the ArrayBuffer as a UintArray
4817
4818
  if (data instanceof ArrayBuffer)
4818
4819
  return new Uint8Array(data);
4820
+ // returns the bigNumbers hex as a UintArray
4819
4821
  if (data._isBigNumber)
4820
4822
  return new TextEncoder().encode(data._hex || data.toHexString());
4821
4823
  // returns the string as a UintArray
@@ -4829,11 +4831,11 @@ const toType = (data) => {
4829
4831
  return new TextEncoder().encode(data.toString());
4830
4832
  throw new Error(`unsuported type ${typeof data || data}`);
4831
4833
  };
4832
- const encode = (proto, input) => {
4834
+ const encode = (proto, input, compress) => {
4833
4835
  const keys = Object.keys(proto);
4834
4836
  const values = Object.values(proto);
4835
4837
  const set = [];
4836
- for (let i = 0; i < keys.length; i++) {
4838
+ for (let i = 0; i < values.length; i++) {
4837
4839
  const token = tokenize(keys[i], values[i]);
4838
4840
  const data = input[token.key];
4839
4841
  if (!token.optional && data === undefined)
@@ -4846,14 +4848,14 @@ const encode = (proto, input) => {
4846
4848
  }
4847
4849
  return index$5(set);
4848
4850
  };
4849
- const decode = (proto, uint8Array) => {
4851
+ const decode = (proto, uint8Array, compressed) => {
4850
4852
  let deconcated = index$4(uint8Array);
4851
4853
  const output = {};
4852
4854
  const keys = Object.keys(proto);
4853
4855
  const values = Object.values(proto);
4854
4856
  if (keys.length !== deconcated.length)
4855
4857
  console.warn(`length mismatch: expected ${keys.length} got ${uint8Array.length}`);
4856
- for (let i = 0; i < keys.length; i++) {
4858
+ for (let i = 0; i < values.length; i++) {
4857
4859
  const token = tokenize(keys[i], values[i]);
4858
4860
  if (isUint8Array(token.type))
4859
4861
  output[token.key] = deconcated[i];
@@ -5822,7 +5824,7 @@ let FormatInterface$1 = class FormatInterface extends BasicInterface$1 {
5822
5824
  this.fromUint8Array(buffer);
5823
5825
  else if (buffer instanceof ArrayBuffer)
5824
5826
  this.fromArrayBuffer(buffer);
5825
- else if (buffer instanceof FormatInterface$1 && buffer?.name === this.name)
5827
+ else if (buffer instanceof FormatInterface && buffer?.name === this.name)
5826
5828
  return buffer;
5827
5829
  else if (typeof buffer === 'string') {
5828
5830
  if (this.isHex(buffer))
@@ -5964,7 +5966,7 @@ class TransactionMessage extends FormatInterface {
5964
5966
 
5965
5967
  var proto$4 = {
5966
5968
  address: String(),
5967
- reward: String()
5969
+ reward: BigNumber.from(0)
5968
5970
  };
5969
5971
 
5970
5972
  class ValidatorMessage extends FormatInterface {
@@ -5981,8 +5983,8 @@ var proto$3 = {
5981
5983
  index: Number(),
5982
5984
  previousHash: String(),
5983
5985
  timestamp: Number(),
5984
- reward: String(),
5985
- fees: String(),
5986
+ reward: BigNumber.from(0),
5987
+ fees: BigNumber.from(0),
5986
5988
  transactions: new Uint8Array(),
5987
5989
  validators: new Uint8Array()
5988
5990
  };
@@ -1,5 +1,5 @@
1
- import { M as MultiWallet, e as encrypt, b as base58$1 } from './node-browser-35d521b9.js';
2
- import './contract-32687834.js';
1
+ import { M as MultiWallet, e as encrypt, b as base58$1 } from './node-browser-aa07a41d.js';
2
+ import './contract-f76383c3.js';
3
3
 
4
4
  /**
5
5
  * @params {String} network
@@ -1,5 +1,5 @@
1
- import { F as FormatInterface } from './node-browser-35d521b9.js';
2
- import './contract-32687834.js';
1
+ import { F as FormatInterface } from './node-browser-aa07a41d.js';
2
+ import './contract-f76383c3.js';
3
3
 
4
4
  var proto$b = {
5
5
  data: new Uint8Array(),
@@ -1,4 +1,4 @@
1
- import { C as ContractMessage, T as TransactionMessage, d as BlockMessage, e as BWMessage, f as BWRequestMessage, V as ValidatorMessage } from './contract-32687834.js';
1
+ import { C as ContractMessage, T as TransactionMessage, d as BlockMessage, e as BWMessage, f as BWRequestMessage, V as ValidatorMessage } from './contract-f76383c3.js';
2
2
 
3
3
  var nodeConfig = async (config = {
4
4
  network: 'leofcoin:peach',
@@ -4868,12 +4868,13 @@ const isUint8Array$1 = (type) => type === 'uint8Array';
4868
4868
  const isBigNumber = (type) => type === 'bigNumber';
4869
4869
  const tokenize = (key, value) => {
4870
4870
  const optional = key.endsWith('?');
4871
- let type = value;
4872
- type = Array.isArray(type) ? 'array' : typeof type;
4873
- if (value instanceof Uint8Array)
4871
+ let type = value === undefined ? key : value;
4872
+ if (type instanceof Uint8Array)
4874
4873
  type = 'uint8Array';
4875
- else if (value._isBigNumber)
4874
+ else if (type?._isBigNumber || type.isBigNumber)
4876
4875
  type = 'bigNumber';
4876
+ else
4877
+ type = Array.isArray(type) ? 'array' : typeof type;
4877
4878
  const parts = key.split('?');
4878
4879
  const minimumLength = parts[2]?.includes('min') ? parts[2].split['min:'][1] : 0;
4879
4880
  return { type, optional, key: parts[0], minimumLength };
@@ -4885,6 +4886,7 @@ const toType = (data) => {
4885
4886
  // returns the ArrayBuffer as a UintArray
4886
4887
  if (data instanceof ArrayBuffer)
4887
4888
  return new Uint8Array(data);
4889
+ // returns the bigNumbers hex as a UintArray
4888
4890
  if (data._isBigNumber)
4889
4891
  return new TextEncoder().encode(data._hex || data.toHexString());
4890
4892
  // returns the string as a UintArray
@@ -4898,11 +4900,11 @@ const toType = (data) => {
4898
4900
  return new TextEncoder().encode(data.toString());
4899
4901
  throw new Error(`unsuported type ${typeof data || data}`);
4900
4902
  };
4901
- const encode$3 = (proto, input) => {
4903
+ const encode$3 = (proto, input, compress) => {
4902
4904
  const keys = Object.keys(proto);
4903
4905
  const values = Object.values(proto);
4904
4906
  const set = [];
4905
- for (let i = 0; i < keys.length; i++) {
4907
+ for (let i = 0; i < values.length; i++) {
4906
4908
  const token = tokenize(keys[i], values[i]);
4907
4909
  const data = input[token.key];
4908
4910
  if (!token.optional && data === undefined)
@@ -4915,14 +4917,14 @@ const encode$3 = (proto, input) => {
4915
4917
  }
4916
4918
  return index$6(set);
4917
4919
  };
4918
- const decode$4 = (proto, uint8Array) => {
4920
+ const decode$4 = (proto, uint8Array, compressed) => {
4919
4921
  let deconcated = index$5(uint8Array);
4920
4922
  const output = {};
4921
4923
  const keys = Object.keys(proto);
4922
4924
  const values = Object.values(proto);
4923
4925
  if (keys.length !== deconcated.length)
4924
4926
  console.warn(`length mismatch: expected ${keys.length} got ${uint8Array.length}`);
4925
- for (let i = 0; i < keys.length; i++) {
4927
+ for (let i = 0; i < values.length; i++) {
4926
4928
  const token = tokenize(keys[i], values[i]);
4927
4929
  if (isUint8Array$1(token.type))
4928
4930
  output[token.key] = deconcated[i];
@@ -6009,7 +6011,7 @@ let FormatInterface$1 = class FormatInterface extends BasicInterface$1 {
6009
6011
  this.fromUint8Array(buffer);
6010
6012
  else if (buffer instanceof ArrayBuffer)
6011
6013
  this.fromArrayBuffer(buffer);
6012
- else if (buffer instanceof FormatInterface$1 && buffer?.name === this.name)
6014
+ else if (buffer instanceof FormatInterface && buffer?.name === this.name)
6013
6015
  return buffer;
6014
6016
  else if (typeof buffer === 'string') {
6015
6017
  if (this.isHex(buffer))
@@ -20263,7 +20265,7 @@ class Identity {
20263
20265
  globalThis.peernet.selectedAccount = new TextDecoder().decode(selected);
20264
20266
  }
20265
20267
  else {
20266
- const importee = await import(/* webpackChunkName: "generate-account" */ './index-2c7d7136-110b02cd.js');
20268
+ const importee = await import(/* webpackChunkName: "generate-account" */ './index-2c2a9d47-00b5d0df.js');
20267
20269
  const { identity, accounts } = await importee.default(password, this.network);
20268
20270
  await globalThis.accountStore.put('public', JSON.stringify({ walletId: identity.walletId }));
20269
20271
  await globalThis.walletStore.put('version', String(1));
@@ -20434,7 +20436,7 @@ class Peernet {
20434
20436
  this.root = options.root;
20435
20437
  const { RequestMessage, ResponseMessage, PeerMessage, PeerMessageResponse, PeernetMessage, DHTMessage, DHTMessageResponse, DataMessage, DataMessageResponse, PsMessage, ChatMessage, PeernetFile
20436
20438
  // FolderMessageResponse
20437
- } = await import(/* webpackChunkName: "messages" */ './messages-bcb7873b-d8249d98.js');
20439
+ } = await import(/* webpackChunkName: "messages" */ './messages-6cc87ed7-c16a1408.js');
20438
20440
  /**
20439
20441
  * proto Object containing protos
20440
20442
  * @type {Object}
@@ -20506,7 +20508,7 @@ class Peernet {
20506
20508
  if (this.#starting || this.#started)
20507
20509
  return;
20508
20510
  this.#starting = true;
20509
- const importee = await import('./client-91364a04-ef77946f.js');
20511
+ const importee = await import('./client-e3216b03-fd2d3b03.js');
20510
20512
  /**
20511
20513
  * @access public
20512
20514
  * @type {PeernetClient}
@@ -1,2 +1,2 @@
1
- export { N as default } from './node-browser-35d521b9.js';
2
- import './contract-32687834.js';
1
+ export { N as default } from './node-browser-aa07a41d.js';
2
+ import './contract-f76383c3.js';
@@ -4732,12 +4732,13 @@ const isUint8Array = (type) => type === 'uint8Array';
4732
4732
  const isBigNumber = (type) => type === 'bigNumber';
4733
4733
  const tokenize = (key, value) => {
4734
4734
  const optional = key.endsWith('?');
4735
- let type = value;
4736
- type = Array.isArray(type) ? 'array' : typeof type;
4737
- if (value instanceof Uint8Array)
4735
+ let type = value === undefined ? key : value;
4736
+ if (type instanceof Uint8Array)
4738
4737
  type = 'uint8Array';
4739
- else if (value._isBigNumber)
4738
+ else if (type?._isBigNumber || type.isBigNumber)
4740
4739
  type = 'bigNumber';
4740
+ else
4741
+ type = Array.isArray(type) ? 'array' : typeof type;
4741
4742
  const parts = key.split('?');
4742
4743
  const minimumLength = parts[2]?.includes('min') ? parts[2].split['min:'][1] : 0;
4743
4744
  return { type, optional, key: parts[0], minimumLength };
@@ -4749,6 +4750,7 @@ const toType = (data) => {
4749
4750
  // returns the ArrayBuffer as a UintArray
4750
4751
  if (data instanceof ArrayBuffer)
4751
4752
  return new Uint8Array(data);
4753
+ // returns the bigNumbers hex as a UintArray
4752
4754
  if (data._isBigNumber)
4753
4755
  return new TextEncoder().encode(data._hex || data.toHexString());
4754
4756
  // returns the string as a UintArray
@@ -4762,11 +4764,11 @@ const toType = (data) => {
4762
4764
  return new TextEncoder().encode(data.toString());
4763
4765
  throw new Error(`unsuported type ${typeof data || data}`);
4764
4766
  };
4765
- const encode = (proto, input) => {
4767
+ const encode = (proto, input, compress) => {
4766
4768
  const keys = Object.keys(proto);
4767
4769
  const values = Object.values(proto);
4768
4770
  const set = [];
4769
- for (let i = 0; i < keys.length; i++) {
4771
+ for (let i = 0; i < values.length; i++) {
4770
4772
  const token = tokenize(keys[i], values[i]);
4771
4773
  const data = input[token.key];
4772
4774
  if (!token.optional && data === undefined)
@@ -4779,14 +4781,14 @@ const encode = (proto, input) => {
4779
4781
  }
4780
4782
  return index$5(set);
4781
4783
  };
4782
- const decode = (proto, uint8Array) => {
4784
+ const decode = (proto, uint8Array, compressed) => {
4783
4785
  let deconcated = index$4(uint8Array);
4784
4786
  const output = {};
4785
4787
  const keys = Object.keys(proto);
4786
4788
  const values = Object.values(proto);
4787
4789
  if (keys.length !== deconcated.length)
4788
4790
  console.warn(`length mismatch: expected ${keys.length} got ${uint8Array.length}`);
4789
- for (let i = 0; i < keys.length; i++) {
4791
+ for (let i = 0; i < values.length; i++) {
4790
4792
  const token = tokenize(keys[i], values[i]);
4791
4793
  if (isUint8Array(token.type))
4792
4794
  output[token.key] = deconcated[i];
@@ -5755,7 +5757,7 @@ let FormatInterface$1 = class FormatInterface extends BasicInterface$1 {
5755
5757
  this.fromUint8Array(buffer);
5756
5758
  else if (buffer instanceof ArrayBuffer)
5757
5759
  this.fromArrayBuffer(buffer);
5758
- else if (buffer instanceof FormatInterface$1 && buffer?.name === this.name)
5760
+ else if (buffer instanceof FormatInterface && buffer?.name === this.name)
5759
5761
  return buffer;
5760
5762
  else if (typeof buffer === 'string') {
5761
5763
  if (this.isHex(buffer))
@@ -5896,7 +5898,7 @@ class TransactionMessage extends FormatInterface {
5896
5898
 
5897
5899
  var proto$1 = {
5898
5900
  address: String(),
5899
- reward: String()
5901
+ reward: BigNumber.from(0)
5900
5902
  };
5901
5903
 
5902
5904
  class ValidatorMessage extends FormatInterface {
@@ -5913,8 +5915,8 @@ var proto = {
5913
5915
  index: Number(),
5914
5916
  previousHash: String(),
5915
5917
  timestamp: Number(),
5916
- reward: String(),
5917
- fees: String(),
5918
+ reward: BigNumber.from(0),
5919
+ fees: BigNumber.from(0),
5918
5920
  transactions: new Uint8Array(),
5919
5921
  validators: new Uint8Array()
5920
5922
  };
@@ -4732,12 +4732,13 @@ const isUint8Array = (type) => type === 'uint8Array';
4732
4732
  const isBigNumber = (type) => type === 'bigNumber';
4733
4733
  const tokenize = (key, value) => {
4734
4734
  const optional = key.endsWith('?');
4735
- let type = value;
4736
- type = Array.isArray(type) ? 'array' : typeof type;
4737
- if (value instanceof Uint8Array)
4735
+ let type = value === undefined ? key : value;
4736
+ if (type instanceof Uint8Array)
4738
4737
  type = 'uint8Array';
4739
- else if (value._isBigNumber)
4738
+ else if (type?._isBigNumber || type.isBigNumber)
4740
4739
  type = 'bigNumber';
4740
+ else
4741
+ type = Array.isArray(type) ? 'array' : typeof type;
4741
4742
  const parts = key.split('?');
4742
4743
  const minimumLength = parts[2]?.includes('min') ? parts[2].split['min:'][1] : 0;
4743
4744
  return { type, optional, key: parts[0], minimumLength };
@@ -4749,6 +4750,7 @@ const toType = (data) => {
4749
4750
  // returns the ArrayBuffer as a UintArray
4750
4751
  if (data instanceof ArrayBuffer)
4751
4752
  return new Uint8Array(data);
4753
+ // returns the bigNumbers hex as a UintArray
4752
4754
  if (data._isBigNumber)
4753
4755
  return new TextEncoder().encode(data._hex || data.toHexString());
4754
4756
  // returns the string as a UintArray
@@ -4762,11 +4764,11 @@ const toType = (data) => {
4762
4764
  return new TextEncoder().encode(data.toString());
4763
4765
  throw new Error(`unsuported type ${typeof data || data}`);
4764
4766
  };
4765
- const encode = (proto, input) => {
4767
+ const encode = (proto, input, compress) => {
4766
4768
  const keys = Object.keys(proto);
4767
4769
  const values = Object.values(proto);
4768
4770
  const set = [];
4769
- for (let i = 0; i < keys.length; i++) {
4771
+ for (let i = 0; i < values.length; i++) {
4770
4772
  const token = tokenize(keys[i], values[i]);
4771
4773
  const data = input[token.key];
4772
4774
  if (!token.optional && data === undefined)
@@ -4779,14 +4781,14 @@ const encode = (proto, input) => {
4779
4781
  }
4780
4782
  return index$5(set);
4781
4783
  };
4782
- const decode = (proto, uint8Array) => {
4784
+ const decode = (proto, uint8Array, compressed) => {
4783
4785
  let deconcated = index$4(uint8Array);
4784
4786
  const output = {};
4785
4787
  const keys = Object.keys(proto);
4786
4788
  const values = Object.values(proto);
4787
4789
  if (keys.length !== deconcated.length)
4788
4790
  console.warn(`length mismatch: expected ${keys.length} got ${uint8Array.length}`);
4789
- for (let i = 0; i < keys.length; i++) {
4791
+ for (let i = 0; i < values.length; i++) {
4790
4792
  const token = tokenize(keys[i], values[i]);
4791
4793
  if (isUint8Array(token.type))
4792
4794
  output[token.key] = deconcated[i];
@@ -5755,7 +5757,7 @@ let FormatInterface$1 = class FormatInterface extends BasicInterface$1 {
5755
5757
  this.fromUint8Array(buffer);
5756
5758
  else if (buffer instanceof ArrayBuffer)
5757
5759
  this.fromArrayBuffer(buffer);
5758
- else if (buffer instanceof FormatInterface$1 && buffer?.name === this.name)
5760
+ else if (buffer instanceof FormatInterface && buffer?.name === this.name)
5759
5761
  return buffer;
5760
5762
  else if (typeof buffer === 'string') {
5761
5763
  if (this.isHex(buffer))
@@ -5896,7 +5898,7 @@ class TransactionMessage extends FormatInterface {
5896
5898
 
5897
5899
  var proto$2 = {
5898
5900
  address: String(),
5899
- reward: String()
5901
+ reward: BigNumber.from(0)
5900
5902
  };
5901
5903
 
5902
5904
  class ValidatorMessage extends FormatInterface {
@@ -5913,8 +5915,8 @@ var proto$1 = {
5913
5915
  index: Number(),
5914
5916
  previousHash: String(),
5915
5917
  timestamp: Number(),
5916
- reward: String(),
5917
- fees: String(),
5918
+ reward: BigNumber.from(0),
5919
+ fees: BigNumber.from(0),
5918
5920
  transactions: new Uint8Array(),
5919
5921
  validators: new Uint8Array()
5920
5922
  };
package/exports/chain.js CHANGED
@@ -373,7 +373,6 @@ class Transaction extends Protocol {
373
373
  throw new Error(`transaction not signed`);
374
374
  if (message.decoded.nonce === undefined)
375
375
  throw new Error(`nonce required`);
376
- message = new TransactionMessage(message.encoded);
377
376
  try {
378
377
  await this.validateNonce(message.decoded.from, message.decoded.nonce);
379
378
  // todo check if signature is valid
@@ -457,6 +456,8 @@ globalThis.BigNumber = BigNumber;
457
456
  // check if browser or local
458
457
  class Chain extends Contract {
459
458
  #state;
459
+ #lastResolved;
460
+ #slotTime = 10000;
460
461
  id;
461
462
  utils;
462
463
  /** {Address[]} */
@@ -716,7 +717,7 @@ class Chain extends Contract {
716
717
  return this;
717
718
  }
718
719
  async #invalidTransaction(hash) {
719
- await transactionPoolStore.delete(hash);
720
+ await globalThis.transactionPoolStore.delete(hash);
720
721
  console.log(`removed invalid transaction: ${hash}`);
721
722
  }
722
723
  async #validatorTimeout(validatorInfo) {
@@ -733,6 +734,19 @@ class Chain extends Contract {
733
734
  return 'synced';
734
735
  }
735
736
  async #syncChain(lastBlock) {
737
+ let current;
738
+ const timeout = () => current = setTimeout(() => {
739
+ if (this.#chainSyncing) {
740
+ if (this.#lastResolved + 10000 > Date.now())
741
+ timeout();
742
+ else {
743
+ this.#chainSyncing = false;
744
+ console.log('resyncing');
745
+ this.#syncChain(lastBlock);
746
+ }
747
+ }
748
+ }, 10000);
749
+ timeout();
736
750
  if (this.#chainSyncing || !lastBlock || !lastBlock.hash || !lastBlock.hash)
737
751
  return;
738
752
  this.#chainSyncing = true;
@@ -757,6 +771,7 @@ class Chain extends Contract {
757
771
  await this.#loadBlocks(this.blocks.slice(start));
758
772
  await this.#updateState(new BlockMessage(this.#blocks[this.#blocks.length - 1]));
759
773
  }
774
+ clearTimeout(current);
760
775
  this.#chainSyncing = false;
761
776
  }
762
777
  async #prepareRequest(request) {
@@ -832,6 +847,7 @@ class Chain extends Contract {
832
847
  this.#blocks[index] = { hash, ...block.decoded };
833
848
  this.#blockHashMap.set(hash, index);
834
849
  console.log(`resolved block: ${hash} @${index} ${formatBytes(size)}`);
850
+ this.#lastResolved = Date.now();
835
851
  if (previousHash !== '0x0') {
836
852
  return this.resolveBlock(previousHash);
837
853
  }
@@ -859,9 +875,12 @@ class Chain extends Contract {
859
875
  * @param {Block[]} blocks
860
876
  */
861
877
  async #loadBlocks(blocks) {
878
+ let poolTransactionKeys = await globalThis.transactionPoolStore.keys();
862
879
  for (const block of blocks) {
863
880
  if (block && !block.loaded) {
864
881
  for (const transaction of block.transactions) {
882
+ if (poolTransactionKeys.includes(transaction.hash))
883
+ await globalThis.transactionPoolStore.delete(transaction.hash);
865
884
  try {
866
885
  await this.#machine.execute(transaction.to, transaction.method, transaction.params);
867
886
  if (transaction.to === nativeToken) {
@@ -975,11 +994,12 @@ class Chain extends Contract {
975
994
  if (Object.keys(transactions)?.length === 0)
976
995
  return;
977
996
  const keys = await globalThis.transactionPoolStore.keys();
997
+ const timestamp = Date.now();
978
998
  let block = {
979
999
  transactions: [],
980
1000
  validators: [],
981
1001
  fees: BigNumber.from(0),
982
- timestamp: Date.now(),
1002
+ timestamp,
983
1003
  previousHash: '',
984
1004
  reward: parseUnits('150'),
985
1005
  index: 0
@@ -989,18 +1009,27 @@ class Chain extends Contract {
989
1009
  transactions = transactions.sort((a, b) => a.nonce - b.nonce);
990
1010
  for (let transaction of transactions) {
991
1011
  const hash = await transaction.hash();
992
- try {
993
- const result = await this.#executeTransaction({ ...transaction.decoded, hash });
994
- console.log({ result });
995
- block.transactions.push({ hash, ...transaction.decoded });
996
- block.fees = block.fees.add(await calculateFee(transaction.decoded));
997
- await globalThis.accountsStore.put(transaction.decoded.from, new TextEncoder().encode(String(transaction.decoded.nonce)));
998
- }
999
- catch (e) {
1000
- console.log(keys.includes(hash));
1001
- console.log({ e });
1002
- console.log(hash);
1012
+ const doubleTransaction = this.#blocks.filter(({ transaction }) => transaction.hash === hash);
1013
+ if (doubleTransaction.length > 0) {
1003
1014
  await globalThis.transactionPoolStore.delete(hash);
1015
+ await globalThis.peernet.publish('invalid-transaction', hash);
1016
+ }
1017
+ else {
1018
+ if (timestamp + this.#slotTime > Date.now()) {
1019
+ try {
1020
+ const result = await this.#executeTransaction({ ...transaction.decoded, hash });
1021
+ console.log({ result });
1022
+ block.transactions.push({ hash, ...transaction.decoded });
1023
+ block.fees = block.fees.add(await calculateFee(transaction.decoded));
1024
+ await globalThis.accountsStore.put(transaction.decoded.from, new TextEncoder().encode(String(transaction.decoded.nonce)));
1025
+ }
1026
+ catch (e) {
1027
+ console.log(keys.includes(hash));
1028
+ console.log({ e });
1029
+ console.log(hash);
1030
+ await globalThis.transactionPoolStore.delete(hash);
1031
+ }
1032
+ }
1004
1033
  }
1005
1034
  }
1006
1035
  console.log(block.transactions);
@@ -1068,7 +1097,6 @@ class Chain extends Contract {
1068
1097
  await Promise.all(block.transactions
1069
1098
  .map(async (transaction) => globalThis.transactionPoolStore.delete(transaction.hash)));
1070
1099
  let blockMessage = await new BlockMessage(block);
1071
- blockMessage = await new BlockMessage(blockMessage.encoded);
1072
1100
  const hash = await blockMessage.hash();
1073
1101
  await globalThis.peernet.put(hash, blockMessage.encoded, 'block');
1074
1102
  await this.#updateState(blockMessage);
@@ -1083,18 +1111,21 @@ class Chain extends Contract {
1083
1111
  // transactionStore.put(message.hash, message.encoded)
1084
1112
  }
1085
1113
  async #addTransaction(transaction) {
1114
+ transaction = await new TransactionMessage(transaction);
1115
+ const hash = await transaction.hash();
1086
1116
  try {
1087
- transaction = await new TransactionMessage(transaction);
1088
- transaction = await new TransactionMessage(transaction.encoded);
1089
- const hash = await transaction.hash();
1090
1117
  const has = await globalThis.transactionPoolStore.has(hash);
1091
- if (!has)
1118
+ if (!has) {
1092
1119
  await globalThis.transactionPoolStore.put(hash, transaction.encoded);
1093
- if (this.#participating && !this.#runningEpoch)
1094
- this.#runEpoch();
1120
+ if (this.#participating && !this.#runningEpoch)
1121
+ this.#runEpoch();
1122
+ }
1123
+ else
1124
+ globalThis.peernet.publish('invalid-transaction', hash);
1095
1125
  }
1096
1126
  catch (e) {
1097
1127
  console.log(e);
1128
+ globalThis.peernet.publish('invalid-transaction', hash);
1098
1129
  throw new Error('invalid transaction');
1099
1130
  }
1100
1131
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leofcoin/chain",
3
- "version": "1.4.43",
3
+ "version": "1.4.45",
4
4
  "description": "Official javascript implementation",
5
5
  "exports": {
6
6
  "./node": "./exports/node.js",