@leofcoin/chain 1.5.67 → 1.5.69

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.
@@ -12430,55 +12430,56 @@ class ValidatorMessage extends FormatInterface {
12430
12430
  }
12431
12431
 
12432
12432
  var proto$1 = {
12433
- index: Number(),
12434
- previousHash: String(),
12435
- timestamp: Number(),
12436
- reward: BigNumber.from(0),
12437
- fees: BigNumber.from(0),
12438
- transactions: new Uint8Array(),
12439
- validators: new Uint8Array()
12433
+ index: Number(),
12434
+ previousHash: String(),
12435
+ timestamp: Number(),
12436
+ reward: BigNumber.from(0),
12437
+ fees: BigNumber.from(0),
12438
+ transactions: new Uint8Array(),
12439
+ validators: new Uint8Array()
12440
12440
  };
12441
12441
 
12442
12442
  class BlockMessage extends FormatInterface {
12443
- get messageName() {
12444
- return 'BlockMessage'
12445
- }
12446
- constructor(buffer) {
12447
- if (buffer instanceof BlockMessage) return buffer
12448
- const name = 'block-message';
12449
- super(buffer, proto$1, { name });
12450
- }
12451
- encode(decoded) {
12452
- decoded = decoded || this.decoded;
12453
- const validators = [];
12454
- const transactions = [];
12455
- for (const validator of decoded.validators) {
12456
- if (validator instanceof ValidatorMessage) validators.push(validator.encode());
12457
- else validators.push(new ValidatorMessage(validator).encode());
12458
- }
12459
- for (const transaction of decoded.transactions) {
12460
- if (transaction instanceof TransactionMessage) transactions.push(transaction.encode());
12461
- else transactions.push(new TransactionMessage(transaction).encode());
12462
- }
12463
- return super.encode({
12464
- ...decoded,
12465
- validators: index$5(validators),
12466
- transactions: index$5(transactions)
12467
- })
12468
- }
12469
- decode(encoded) {
12470
- encoded = encoded || this.encoded;
12471
- super.decode(encoded);
12472
- // @ts-ignore
12473
- this.decoded.transactions = index$4(this.decoded.transactions).map(
12474
- (transaction) => new TransactionMessage(transaction).decoded
12475
- );
12476
- // @ts-ignore
12477
- this.decoded.validators = index$4(this.decoded.validators).map(
12478
- (validator) => new ValidatorMessage(validator).decoded
12479
- );
12480
- return this.decoded
12481
- }
12443
+ get messageName() {
12444
+ return 'BlockMessage';
12445
+ }
12446
+ constructor(buffer) {
12447
+ if (buffer instanceof BlockMessage)
12448
+ return buffer;
12449
+ const name = 'block-message';
12450
+ super(buffer, proto$1, { name });
12451
+ }
12452
+ encode(decoded) {
12453
+ decoded = decoded || this.decoded;
12454
+ const validators = [];
12455
+ const transactions = [];
12456
+ for (const validator of decoded.validators) {
12457
+ if (validator instanceof ValidatorMessage)
12458
+ validators.push(validator.encode());
12459
+ else
12460
+ validators.push(new ValidatorMessage(validator).encode());
12461
+ }
12462
+ for (const transaction of decoded.transactions) {
12463
+ if (transaction instanceof TransactionMessage)
12464
+ transactions.push(transaction.encode());
12465
+ else
12466
+ transactions.push(new TransactionMessage(transaction).encode());
12467
+ }
12468
+ return super.encode({
12469
+ ...decoded,
12470
+ validators: index$5(validators),
12471
+ transactions: index$5(transactions)
12472
+ });
12473
+ }
12474
+ decode(encoded) {
12475
+ encoded = encoded || this.encoded;
12476
+ super.decode(encoded);
12477
+ // @ts-ignore
12478
+ this.decoded.transactions = index$4(this.decoded.transactions).map((transaction) => new TransactionMessage(transaction).decoded);
12479
+ // @ts-ignore
12480
+ this.decoded.validators = index$4(this.decoded.validators).map((validator) => new ValidatorMessage(validator).decoded);
12481
+ return this.decoded;
12482
+ }
12482
12483
  }
12483
12484
 
12484
12485
  var proto = {
package/exports/chain.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import '@vandeurenglenn/debug';
2
2
  import { formatBytes, BigNumber, formatUnits, parseUnits } from '@leofcoin/utils';
3
3
  import { TransactionMessage, BlockMessage, ContractMessage, BWMessage, BWRequestMessage } from '@leofcoin/messages';
4
- import addresses, { contractFactory, nativeToken, validators, nameService } from '@leofcoin/addresses';
4
+ import addresses, { contractFactory } from '@leofcoin/addresses';
5
5
  import { calculateFee, createContractMessage, signTransaction, contractFactoryMessage, nativeTokenMessage, validatorsMessage, nameServiceMessage } from '@leofcoin/lib';
6
6
  import semver from 'semver';
7
7
  import { randombytes } from '@leofcoin/crypto';
@@ -9,7 +9,7 @@ import EasyWorker from '@vandeurenglenn/easy-worker';
9
9
  import { ContractDeploymentError, ExecutionError, isResolveError, ResolveError, isExecutionError } from '@leofcoin/errors';
10
10
 
11
11
  const limit = 1800;
12
- const transactionLimit = 1800;
12
+ const transactionLimit = 1000;
13
13
  const requestTimeout = 30000;
14
14
  const syncTimeout = 30000;
15
15
  class Protocol {
@@ -158,10 +158,7 @@ class Transaction extends Protocol {
158
158
  }
159
159
  async createTransaction(transaction) {
160
160
  return {
161
- from: transaction.from,
162
- to: transaction.to,
163
- method: transaction.method,
164
- params: transaction.params,
161
+ ...transaction,
165
162
  timestamp: transaction.timestamp || Date.now(),
166
163
  nonce: transaction.nonce || (await this.getNonce(transaction.from)) + 1
167
164
  };
@@ -273,19 +270,17 @@ class Contract extends Transaction {
273
270
  // import State from './state'
274
271
  const debug$2 = globalThis.createDebugger('leofcoin/machine');
275
272
  class Machine {
276
- #contracts = {};
277
- #nonces = {};
278
273
  constructor(blocks) {
274
+ this.states = {
275
+ states: {},
276
+ lastBlock: {
277
+ index: 0,
278
+ hash: ''
279
+ }
280
+ };
279
281
  // @ts-ignore
280
282
  return this.#init(blocks);
281
283
  }
282
- #createMessage(sender = peernet.selectedAccount) {
283
- return {
284
- sender,
285
- call: this.execute,
286
- staticCall: this.get.bind(this)
287
- };
288
- }
289
284
  async #onmessage(data) {
290
285
  switch (data.type) {
291
286
  case 'transactionLoaded': {
@@ -336,12 +331,54 @@ class Machine {
336
331
  pubsub.publish(data.id, data.value || false);
337
332
  break;
338
333
  }
334
+ case 'ask': {
335
+ if (data.question === 'contract') {
336
+ const input = await peernet.get(data.input, 'contract');
337
+ this.worker.postMessage({ id: data.id, input });
338
+ }
339
+ }
340
+ }
341
+ }
342
+ async updateState() {
343
+ try {
344
+ if ((await this.lastBlock).index > this.states.lastBlock.index) {
345
+ // todo only get state for changed contracts
346
+ const blocks = (await this.blocks).slice(this.states.lastBlock.index);
347
+ const contractsToGet = blocks.reduce((set, current) => {
348
+ for (const transaction of current.transactions) {
349
+ const contract = transaction.to;
350
+ if (!set.includes(contract))
351
+ set.push(contract);
352
+ }
353
+ return set;
354
+ }, []);
355
+ const state = {};
356
+ console.log({ contractsToGet });
357
+ if (!contractsToGet.includes(addresses.contractFactory))
358
+ contractsToGet.push(addresses.contractFactory);
359
+ if (!contractsToGet.includes(addresses.nativeToken))
360
+ contractsToGet.push(addresses.nativeToken);
361
+ if (!contractsToGet.includes(addresses.nameService))
362
+ contractsToGet.push(addresses.nameService);
363
+ if (!contractsToGet.includes(addresses.validators))
364
+ contractsToGet.push(addresses.validators);
365
+ await Promise.all(contractsToGet.map(async (contract) => {
366
+ const value = await this.#askWorker('get', { contract, method: 'state', params: [] });
367
+ state[contract] = value;
368
+ }));
369
+ await stateStore.put('lastBlock', JSON.stringify(await this.lastBlock));
370
+ await stateStore.put('states', JSON.stringify(state));
371
+ }
372
+ }
373
+ catch (error) {
374
+ console.error(error);
339
375
  }
340
376
  }
341
377
  async #init(blocks) {
342
378
  return new Promise(async (resolve) => {
343
- const machineReady = () => {
379
+ const machineReady = async () => {
344
380
  pubsub.unsubscribe('machine.ready', machineReady);
381
+ await this.updateState();
345
382
  resolve(this);
346
383
  };
347
384
  pubsub.subscribe('machine.ready', machineReady);
@@ -361,18 +398,18 @@ class Machine {
361
398
  type: 'module'
362
399
  });
363
400
  this.worker.onmessage(this.#onmessage.bind(this));
364
- // const blocks = await blockStore.values()
365
- const contracts = await Promise.all([
366
- globalThis.contractStore.get(contractFactory),
367
- globalThis.contractStore.get(nativeToken),
368
- globalThis.contractStore.get(validators),
369
- globalThis.contractStore.get(nameService)
370
- ]);
401
+ if (await stateStore.has('lastBlock')) {
402
+ this.states.lastBlock = JSON.parse(new TextDecoder().decode(await stateStore.get('lastBlock')));
403
+ this.states.states = JSON.parse(new TextDecoder().decode(await stateStore.get('states')));
404
+ console.log({ balances: this.states.states[addresses.nativeToken].balances });
405
+ }
371
406
  const message = {
372
407
  type: 'init',
373
408
  input: {
374
- contracts,
375
409
  blocks,
410
+ fromState: this.states.lastBlock.index > 0,
411
+ lastBlock: this.states.lastBlock,
412
+ state: this.states.states,
376
413
  // @ts-ignore
377
414
  peerid: peernet.peerId
378
415
  }
@@ -692,8 +729,10 @@ class State extends Contract {
692
729
  this.#loadBlockTransactions = (transactions) => Promise.all(transactions.map((transaction) => new TransactionMessage(transaction)));
693
730
  this.#getLastTransactions = async () => {
694
731
  let lastTransactions = (await Promise.all((await this.blocks)
732
+ // @ts-ignore
695
733
  .filter((block) => block.loaded)
696
734
  .slice(-24)
735
+ // @ts-ignore
697
736
  .map((block) => this.#loadBlockTransactions(block.transactions)))).reduce((all, transactions) => [...all, ...transactions], []);
698
737
  return Promise.all(lastTransactions.map((transaction) => transaction.hash()));
699
738
  };
@@ -736,14 +775,40 @@ class State extends Contract {
736
775
  throw error;
737
776
  }
738
777
  try {
739
- await this.resolveBlocks();
778
+ let localBlockHash;
779
+ try {
780
+ const localBlock = await globalThis.chainStore.get('lastBlock');
781
+ localBlockHash = new TextDecoder().decode(localBlock);
782
+ }
783
+ catch (error) { }
784
+ if (localBlockHash && localBlockHash !== '0x0') {
785
+ const blockMessage = new BlockMessage(await peernet.get(localBlockHash, 'block'));
786
+ try {
787
+ const states = {
788
+ lastBlock: JSON.parse(new TextDecoder().decode(await globalThis.stateStore.get('lastBlock')))
789
+ };
790
+ if (blockMessage.decoded.index > states.lastBlock.index)
791
+ await this.resolveBlocks();
792
+ }
793
+ catch (error) {
794
+ // no states found, try resolving blocks
795
+ await this.resolveBlocks();
796
+ }
797
+ }
798
+ else {
799
+ await this.resolveBlocks();
800
+ }
740
801
  this.#machine = await new Machine(this.#blocks);
741
802
  const lastBlock = await this.#machine.lastBlock;
742
- this.updateState(new BlockMessage(lastBlock));
803
+ console.log({ lastBlock });
804
+ if (lastBlock.hash !== '0x0') {
805
+ this.updateState(new BlockMessage(lastBlock));
806
+ }
743
807
  this.#loaded = true;
744
808
  // await this.#loadBlocks(this.#blocks)
745
809
  }
746
810
  catch (error) {
811
+ console.log('e');
747
812
  if (isResolveError(error)) {
748
813
  console.error(error);
749
814
  }
@@ -760,6 +825,7 @@ class State extends Contract {
760
825
  catch (error) {
761
826
  console.error(error);
762
827
  }
828
+ await this.#machine.updateState();
763
829
  }
764
830
  getLatestBlock() {
765
831
  // @ts-ignore
@@ -780,9 +846,9 @@ class State extends Contract {
780
846
  }
781
847
  async #resolveBlock(hash) {
782
848
  let index = this.#blockHashMap.get(hash);
783
- if (this.#blocks[index - 1]) {
784
- if (this.#blocks[index - 1].previousHash !== '0x0') {
785
- return this.resolveBlock(this.#blocks[index - 1].previousHash);
849
+ if (this.#blocks[index]) {
850
+ if (this.#blocks[index].previousHash !== '0x0') {
851
+ return this.resolveBlock(this.#blocks[index].previousHash);
786
852
  }
787
853
  else {
788
854
  return;
@@ -793,11 +859,11 @@ class State extends Contract {
793
859
  index = block.decoded.index;
794
860
  const size = block.encoded.length > 0 ? block.encoded.length : block.encoded.byteLength;
795
861
  this.#totalSize += size;
796
- this.#blocks[index - 1] = { hash, ...block.decoded };
862
+ this.#blocks[index] = { hash, ...block.decoded };
797
863
  this.#blockHashMap.set(hash, index);
798
864
  debug$1(`resolved block: ${hash} @${index} ${formatBytes(size)}`);
799
865
  globalThis.pubsub.publish('block-resolved', { hash, index });
800
- this.#lastResolved = this.#blocks[index - 1];
866
+ this.#lastResolved = this.#blocks[index];
801
867
  this.#lastResolvedTime = Date.now();
802
868
  }
803
869
  catch (error) {
@@ -1209,7 +1275,7 @@ class Chain extends VersionControl {
1209
1275
  console.log('epoch');
1210
1276
  const validators = await this.staticCall(addresses.validators, 'validators');
1211
1277
  console.log({ validators });
1212
- if (!validators[peernet.selectedAccount]?.active)
1278
+ if (!validators.includes(peernet.selectedAccount))
1213
1279
  return;
1214
1280
  const start = Date.now();
1215
1281
  try {
@@ -1469,6 +1535,7 @@ class Chain extends VersionControl {
1469
1535
  }
1470
1536
  // todo filter tx that need to wait on prev nonce
1471
1537
  async #createBlock(limit = this.transactionLimit) {
1538
+ console.log(await globalThis.transactionPoolStore.size());
1472
1539
  // vote for transactions
1473
1540
  if ((await globalThis.transactionPoolStore.size()) === 0)
1474
1541
  return;
@@ -1486,19 +1553,22 @@ class Chain extends VersionControl {
1486
1553
  index: 0
1487
1554
  };
1488
1555
  const latestTransactions = await this.machine.latestTransactions();
1556
+ console.log({ latestTransactions });
1489
1557
  // exclude failing tx
1490
1558
  transactions = await this.promiseTransactions(transactions);
1491
- const priority = transactions.filter((transaction) => transaction.priority);
1492
- await Promise.all(priority
1493
- .sort((a, b) => a.nonce - b.nonce)
1494
- .map((transaction) => this.#handleTransaction(transaction, latestTransactions, block)));
1559
+ const priority = transactions
1560
+ .filter((transaction) => transaction.decoded.priority)
1561
+ .sort((a, b) => a.decoded.nonce - b.decoded.nonce);
1562
+ for (const transaction of priority) {
1563
+ await this.#handleTransaction(transaction, latestTransactions, block);
1564
+ }
1495
1565
  await Promise.all(transactions
1496
- .filter((transaction) => !transaction.priority)
1566
+ .filter((transaction) => !transaction.decoded.priority)
1497
1567
  .map((transaction) => this.#handleTransaction(transaction, latestTransactions, block)));
1498
1568
  // don't add empty block
1499
1569
  if (block.transactions.length === 0)
1500
1570
  return;
1501
- const validators = await this.staticCall(addresses.validators, 'validators');
1571
+ const validators = (await this.staticCall(addresses.validators, 'validators'));
1502
1572
  // block.validators = Object.keys(block.validators).reduce((set, key) => {
1503
1573
  // if (block.validators[key].active) {
1504
1574
  // push({
@@ -1510,27 +1580,25 @@ class Chain extends VersionControl {
1510
1580
  for (const entry of globalThis.peernet.peers) {
1511
1581
  peers[entry[0]] = entry[1];
1512
1582
  }
1513
- for (const validator of Object.keys(validators)) {
1514
- if (validators[validator].active) {
1515
- const peer = peers[validator];
1516
- if (peer && peer.connected && peer.version === this.version) {
1517
- let data = await new BWRequestMessage();
1518
- const node = await globalThis.peernet.prepareMessage(data.encoded);
1519
- try {
1520
- const bw = await peer.request(node.encoded);
1521
- block.validators.push({
1522
- address: validator,
1523
- bw: bw.up + bw.down
1524
- });
1525
- }
1526
- catch { }
1527
- }
1528
- else if (globalThis.peernet.selectedAccount === validator) {
1583
+ for (const validator of validators) {
1584
+ const peer = peers[validator];
1585
+ if (peer && peer.connected && peer.version === this.version) {
1586
+ let data = await new BWRequestMessage();
1587
+ const node = await globalThis.peernet.prepareMessage(data.encoded);
1588
+ try {
1589
+ const bw = await peer.request(node.encoded);
1529
1590
  block.validators.push({
1530
- address: globalThis.peernet.selectedAccount,
1531
- bw: globalThis.peernet.bw.up + globalThis.peernet.bw.down
1591
+ address: validator,
1592
+ bw: bw.up + bw.down
1532
1593
  });
1533
1594
  }
1595
+ catch { }
1596
+ }
1597
+ else if (globalThis.peernet.selectedAccount === validator) {
1598
+ block.validators.push({
1599
+ address: globalThis.peernet.selectedAccount,
1600
+ bw: globalThis.peernet.bw.up + globalThis.peernet.bw.down
1601
+ });
1534
1602
  }
1535
1603
  }
1536
1604
  block.validators = block.validators.map((validator) => {
@@ -1617,8 +1685,9 @@ class Chain extends VersionControl {
1617
1685
  * @param {Address} sender
1618
1686
  * @returns {globalMessage}
1619
1687
  */
1620
- #createMessage(sender = globalThis.peernet.selectedAccount) {
1688
+ #createMessage(sender = globalThis.peernet.selectedAccount, contract) {
1621
1689
  return {
1690
+ contract,
1622
1691
  sender,
1623
1692
  call: this.call,
1624
1693
  staticCall: this.staticCall
@@ -1633,7 +1702,7 @@ class Chain extends VersionControl {
1633
1702
  * @returns
1634
1703
  */
1635
1704
  internalCall(sender, contract, method, parameters) {
1636
- globalThis.msg = this.#createMessage(sender);
1705
+ globalThis.msg = this.#createMessage(sender, contract);
1637
1706
  return this.machine.execute(contract, method, parameters);
1638
1707
  }
1639
1708
  /**
@@ -1644,11 +1713,11 @@ class Chain extends VersionControl {
1644
1713
  * @returns
1645
1714
  */
1646
1715
  call(contract, method, parameters) {
1647
- globalThis.msg = this.#createMessage();
1716
+ globalThis.msg = this.#createMessage(peernet.selectedAccount, contract);
1648
1717
  return this.machine.execute(contract, method, parameters);
1649
1718
  }
1650
1719
  staticCall(contract, method, parameters) {
1651
- globalThis.msg = this.#createMessage();
1720
+ globalThis.msg = this.#createMessage(peernet.selectedAccount, contract);
1652
1721
  return this.machine.get(contract, method, parameters);
1653
1722
  }
1654
1723
  mint(to, amount) {
@@ -2,7 +2,15 @@ import EasyWorker from '@vandeurenglenn/easy-worker';
2
2
  export default class Machine {
3
3
  #private;
4
4
  worker: EasyWorker;
5
+ states: {
6
+ states: {};
7
+ lastBlock: {
8
+ index: number;
9
+ hash: string;
10
+ };
11
+ };
5
12
  constructor(blocks: any);
13
+ updateState(): Promise<void>;
6
14
  /**
7
15
  *
8
16
  * @param {Address} contract
@@ -1,6 +1,6 @@
1
1
  import type { ChainConfig } from './types.js';
2
2
  export declare const limit = 1800;
3
- export declare const transactionLimit = 1800;
3
+ export declare const transactionLimit = 1000;
4
4
  export declare const requestTimeout = 30000;
5
5
  export declare const syncTimeout = 30000;
6
6
  export declare class Protocol {
@@ -0,0 +1,3 @@
1
+ export declare const shouldResolveBlocks: () => void;
2
+ export declare const shouldLoadBlocks: () => void;
3
+ export declare const shouldLoadFromState: () => void;
@@ -30,14 +30,7 @@ export default class Transaction extends Protocol {
30
30
  validateNonce(address: any, nonce: any): Promise<void>;
31
31
  isTransactionMessage(message: any): boolean;
32
32
  createTransactionMessage(transaction: any, signature: any): Promise<TransactionMessage>;
33
- createTransaction(transaction: any): Promise<{
34
- from: any;
35
- to: any;
36
- method: any;
37
- params: any;
38
- timestamp: any;
39
- nonce: any;
40
- }>;
33
+ createTransaction(transaction: any): Promise<any>;
41
34
  sendTransaction(message: any): Promise<{
42
35
  hash: any;
43
36
  data: any;
@@ -1,4 +1,4 @@
1
- import { E as EasyWorker, B as BigNumber, a as BlockMessage } from './worker-CltAyHf1.js';
1
+ import { E as EasyWorker, B as BigNumber, a as BlockMessage } from './worker-CbAak_hM.js';
2
2
 
3
3
  const worker = new EasyWorker();
4
4