@leofcoin/chain 1.10.21 → 1.10.22

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,6 +1,6 @@
1
- import { F as FormatInterface } from './node-browser-Ha4Lvntj.js';
1
+ import { F as FormatInterface } from './node-browser-BMfelxXV.js';
2
2
  import './browser-crypto-CH0ua22L.js';
3
- import './connection-monitor-D-krNiRH.js';
3
+ import './connection-monitor-DMGAhcC0.js';
4
4
  import './index-CvKt4UDE.js';
5
5
  import './sha2-BKcEJzgd.js';
6
6
 
@@ -1,5 +1,5 @@
1
1
  import { F as FormatInterface$2, T as TransactionMessage, C as ContractMessage, n as createHash$1 } from './browser-crypto-CH0ua22L.js';
2
- import { B as BlockMessage, a as BWMessage, V as ValidatorMessage, S as StateMessage, L as LastBlockMessage, D as DEFAULT_NODE_OPTIONS, g as guardPeerMessages } from './connection-monitor-D-krNiRH.js';
2
+ import { B as BlockMessage, b as BWMessage, V as ValidatorMessage, S as StateMessage, L as LastBlockMessage, D as DEFAULT_NODE_OPTIONS, g as guardPeerMessages, c as guardProviderDiscovery } from './connection-monitor-DMGAhcC0.js';
3
3
  import './index-CvKt4UDE.js';
4
4
 
5
5
  var proto = {};
@@ -8510,7 +8510,7 @@ class Identity {
8510
8510
  this.selectedAccount = new TextDecoder().decode(selected);
8511
8511
  }
8512
8512
  else {
8513
- const importee = await import(/* webpackChunkName: "generate-account" */ './index-dTQVgkpf-DOL2rIjp.js');
8513
+ const importee = await import(/* webpackChunkName: "generate-account" */ './index-dTQVgkpf-C6SJ0ZYW.js');
8514
8514
  const { identity, accounts } = await importee.default(password, this.network);
8515
8515
  if (fresh) {
8516
8516
  await globalThis.accountStore.clear();
@@ -16102,7 +16102,7 @@ const blockchainCodecs = [
16102
16102
  },
16103
16103
  {
16104
16104
  name: 'raw-transaction-message',
16105
- codec: '0x772746d',
16105
+ codec: '0x72746d',
16106
16106
  hashAlg: 'keccak-256'
16107
16107
  },
16108
16108
  {
@@ -16147,6 +16147,21 @@ const blockchainCodecs = [
16147
16147
  }
16148
16148
  ];
16149
16149
  const consensusCodecs = [
16150
+ {
16151
+ name: 'beacon-activation-message',
16152
+ codec: '0x62616d',
16153
+ hashAlg: 'keccak-256'
16154
+ },
16155
+ {
16156
+ name: 'beacon-commitment-message',
16157
+ codec: '0x62636d',
16158
+ hashAlg: 'keccak-256'
16159
+ },
16160
+ {
16161
+ name: 'beacon-share-message',
16162
+ codec: '0x62736d',
16163
+ hashAlg: 'keccak-256'
16164
+ },
16150
16165
  {
16151
16166
  name: 'proposal-message',
16152
16167
  codec: '0x70726d',
@@ -16225,7 +16240,7 @@ const peernetCodecs = [
16225
16240
  },
16226
16241
  {
16227
16242
  name: 'peernet-ps',
16228
- codec: '707073',
16243
+ codec: '0x707073',
16229
16244
  hashAlg: 'keccak-256'
16230
16245
  },
16231
16246
  {
@@ -17927,7 +17942,7 @@ class Peernet {
17927
17942
  await getAddress();
17928
17943
  this.storePrefix = options.storePrefix;
17929
17944
  this.root = options.root;
17930
- const { RequestMessage, ResponseMessage, PeerMessage, PeerMessageResponse, PeernetMessage, DHTMessage, DHTMessageResponse, DataMessage, DataMessageResponse, PsMessage, ChatMessage, PeernetFile } = await import(/* webpackChunkName: "messages" */ './messages-DCePyqKC-BSvJxDWZ.js');
17945
+ const { RequestMessage, ResponseMessage, PeerMessage, PeerMessageResponse, PeernetMessage, DHTMessage, DHTMessageResponse, DataMessage, DataMessageResponse, PsMessage, ChatMessage, PeernetFile } = await import(/* webpackChunkName: "messages" */ './messages-DZYCxoZI-D6kIiLKF.js');
17931
17946
  /**
17932
17947
  * proto Object containing protos
17933
17948
  * @type {Object}
@@ -17973,7 +17988,7 @@ class Peernet {
17973
17988
  if (this.#starting || this.#started)
17974
17989
  return;
17975
17990
  this.#starting = true;
17976
- const importee = await import('./client-DKKzPSlb-C_1ug6ux.js');
17991
+ const importee = await import('./client-DbZBfpG6-CYDyUGUC.js');
17977
17992
  /**
17978
17993
  * @access public
17979
17994
  * @type {PeernetClient}
@@ -18776,6 +18791,7 @@ class Node {
18776
18791
  config = { ...DEFAULT_NODE_OPTIONS, ...config };
18777
18792
  this.#node = globalThis.Peernet ? await new globalThis.Peernet(config, password) : await new Peernet(config, password);
18778
18793
  guardPeerMessages(this.#node);
18794
+ guardProviderDiscovery(this.#node);
18779
18795
  await nodeConfig(config);
18780
18796
  globalThis.pubsub.subscribe("chain:ready", async () => {
18781
18797
  if (!this.#node.autoStart) {
@@ -18787,4 +18803,4 @@ class Node {
18787
18803
  }
18788
18804
  }
18789
18805
 
18790
- export { FormatInterface as F, LittlePubSub as L, MultiWallet as M, Node as N, base58$1 as b, createDebugger as c, deflate_1 as d, encrypt as e, getDefaultExportFromCjs as g, inflate_1 as i };
18806
+ export { FormatInterface as F, LittlePubSub as L, MultiWallet as M, Node as N, base58$1 as b, createDebugger as c, encrypt as e, getDefaultExportFromCjs as g };
@@ -1,5 +1,5 @@
1
- export { N as default } from './node-browser-Ha4Lvntj.js';
1
+ export { N as default } from './node-browser-BMfelxXV.js';
2
2
  import './browser-crypto-CH0ua22L.js';
3
- import './connection-monitor-D-krNiRH.js';
3
+ import './connection-monitor-DMGAhcC0.js';
4
4
  import './index-CvKt4UDE.js';
5
5
  import './sha2-BKcEJzgd.js';
package/exports/chain.js CHANGED
@@ -7,39 +7,16 @@ import { MAX_TRANSACTION_BYTES, MAX_BLOCK_TRANSACTION_BYTES, MAX_BLOCK_TRANSACTI
7
7
  import MultiWallet from '@leofcoin/multi-wallet';
8
8
  import { fromBase58 } from '@vandeurenglenn/typed-array-utils';
9
9
  import semver from 'semver';
10
+ import { P as Protocol, C as ConnectionMonitor } from './connection-monitor-h2L8vsS7.js';
10
11
  import { randombytes } from '@leofcoin/crypto';
11
12
  import EasyWorker from '@vandeurenglenn/easy-worker';
12
13
  import { ContractDeploymentError, ExecutionError, isResolveError, ResolveError, isExecutionError } from '@leofcoin/errors';
13
14
  import { P as PROTOCOL_VERSION, R as REACHED_ONE_ZERO_ZERO } from './constants-Dy9i9S_o.js';
14
- import ConnectionMonitor from './connection-monitor.js';
15
15
  import { q as quorumThreshold } from './quorum-S_qdgiAY.js';
16
16
  import { assertHashFormatState } from './hash-format-state.js';
17
17
  import { createChainIdentity, assertChainId, findChainPresence } from '@leofcoin/lib/chain-identity';
18
18
  import '@leofcoin/networks';
19
19
 
20
- const limit = 1800;
21
- const transactionLimit = 2500;
22
- const requestTimeout = 3e4;
23
- const syncTimeout = 3e4;
24
- class Protocol {
25
- constructor(config) {
26
- this.resolveTimeout = 1e4;
27
- if (config?.resolveTimeout) this.resolveTimeout = config.resolveTimeout;
28
- }
29
- get limit() {
30
- return limit;
31
- }
32
- get transactionLimit() {
33
- return transactionLimit;
34
- }
35
- get requestTimeout() {
36
- return requestTimeout;
37
- }
38
- get syncTimeout() {
39
- return syncTimeout;
40
- }
41
- }
42
-
43
20
  const waitForCanonicalTransaction = (pubsub, transactionPool, hash) => new Promise((resolve, reject) => {
44
21
  const completionTopic = `transaction.completed.${hash}`;
45
22
  const cleanup = () => {
@@ -1267,6 +1244,15 @@ const validateChainLink = (localTip, incoming) => {
1267
1244
  return "append";
1268
1245
  };
1269
1246
 
1247
+ const resolveTransactionReference = async (expectedHash, transactionData) => {
1248
+ const transaction = transactionData instanceof TransactionMessage ? transactionData : new TransactionMessage(transactionData);
1249
+ const actualHash = await transaction.hash();
1250
+ if (actualHash !== expectedHash) {
1251
+ throw new Error(`Transaction hash mismatch: expected ${expectedHash}, got ${actualHash}`);
1252
+ }
1253
+ return transaction;
1254
+ };
1255
+
1270
1256
  const debug$1 = createDebugger("leofcoin/state");
1271
1257
  class State extends Contract {
1272
1258
  constructor(config) {
@@ -1283,7 +1269,7 @@ class State extends Contract {
1283
1269
  this.#totalSize = 0;
1284
1270
  this.#canonicalStateQueue = new CanonicalStateQueue();
1285
1271
  this.#loaded = false;
1286
- this.#resolvingHashes = /* @__PURE__ */ new Set();
1272
+ this.#resolvingHashes = /* @__PURE__ */ new Map();
1287
1273
  this._wantList = [];
1288
1274
  this.#chainStateHandler = () => {
1289
1275
  return new globalThis.peernet.protos["peernet-response"]({
@@ -1539,7 +1525,8 @@ class State extends Contract {
1539
1525
  if (!exists) {
1540
1526
  const data = await peernet.get(hash, "transaction");
1541
1527
  if (!data) throw new Error(`missing transaction data for ${hash}`);
1542
- await transactionStore.put(hash, data);
1528
+ const transaction = await resolveTransactionReference(hash, data);
1529
+ await transactionStore.put(hash, transaction.encoded);
1543
1530
  }
1544
1531
  const inPool = await transactionPoolStore.has(hash);
1545
1532
  if (inPool) await transactionPoolStore.delete(hash);
@@ -1547,84 +1534,61 @@ class State extends Contract {
1547
1534
  );
1548
1535
  }
1549
1536
  async #resolveBlock(hash) {
1550
- let index = this.#blockHashMap.get(hash);
1551
- let localHash = "0x0";
1552
- try {
1553
- const rawLocalHash = await globalThis.stateStore.get("lastBlock");
1554
- if (rawLocalHash) {
1555
- const decoded = JSON.parse(new TextDecoder().decode(rawLocalHash));
1556
- localHash = typeof decoded === "string" ? decoded : decoded?.hash ?? "0x0";
1537
+ const localHash = (await this.canonicalTip()).hash;
1538
+ const visited = /* @__PURE__ */ new Set();
1539
+ while (hash !== "0x0" && hash !== localHash) {
1540
+ if (visited.has(hash)) throw new ResolveError(`cyclic block ancestry at ${hash}`);
1541
+ visited.add(hash);
1542
+ const cachedIndex = this.#blockHashMap.get(hash);
1543
+ const cached = this.#blocks[cachedIndex];
1544
+ if (cached) {
1545
+ hash = cached.previousHash;
1546
+ continue;
1557
1547
  }
1558
- } catch (error) {
1559
- debug$1("no local state found");
1560
- }
1561
- if (this.#blocks[index]) {
1562
- const previousHash = this.#blocks[index].previousHash;
1563
- if (previousHash === localHash) return;
1564
- if (previousHash !== "0x0") {
1565
- return this.resolveBlock(previousHash);
1566
- } else {
1567
- return;
1548
+ try {
1549
+ const block = await this.getAndPutBlock(hash);
1550
+ await this.#resolveTransactions(block.decoded.transactions);
1551
+ const index = block.decoded.index;
1552
+ const size = block.encoded.byteLength;
1553
+ this.#totalSize += size;
1554
+ this.#blocks[index] = { hash, ...block.decoded };
1555
+ this.#blockHashMap.set(hash, index);
1556
+ debug$1(`resolved block: ${hash} @${index} ${formatBytes(size)}`);
1557
+ globalThis.pubsub.publish("block-resolved", { hash, index });
1558
+ this.#lastResolved = this.#blocks[index];
1559
+ this.#lastResolvedTime = Date.now();
1560
+ hash = block.decoded.previousHash;
1561
+ } catch (error) {
1562
+ throw new ResolveError(`block: ${hash}`, { cause: error });
1568
1563
  }
1569
1564
  }
1570
- try {
1571
- const block = await this.getAndPutBlock(hash);
1572
- const promises = [];
1573
- if (block.decoded.previousHash !== "0x0" && block.decoded.previousHash !== localHash) {
1574
- promises.push(this.resolveBlock(block.decoded.previousHash));
1575
- }
1576
- promises.push(this.#resolveTransactions(block.decoded.transactions));
1577
- await Promise.all(promises);
1578
- index = block.decoded.index;
1579
- const size = block.encoded.length > 0 ? block.encoded.length : block.encoded.byteLength;
1580
- this.#totalSize += size;
1581
- this.#blocks[index] = { hash, ...block.decoded };
1582
- this.#blockHashMap.set(hash, index);
1583
- debug$1(`resolved block: ${hash} @${index} ${formatBytes(size)}`);
1584
- globalThis.pubsub.publish("block-resolved", { hash, index });
1585
- this.#lastResolved = this.#blocks[index];
1586
- this.#lastResolvedTime = Date.now();
1587
- } catch (error) {
1588
- throw new ResolveError(`block: ${hash}@${index}`, { cause: error });
1589
- }
1590
- return;
1591
1565
  }
1592
1566
  async resolveBlock(hash) {
1593
1567
  if (!hash) throw new Error(`expected hash, got: ${hash}`);
1594
1568
  if (hash === "0x0") return;
1595
- if (this.#resolvingHashes.has(hash)) return;
1596
- this.#resolvingHashes.add(hash);
1597
- const isEntering = this.#resolvingHashes.size === 1;
1569
+ const existing = this.#resolvingHashes.get(hash);
1570
+ if (existing) return existing;
1598
1571
  this.#resolving = true;
1599
- try {
1600
- if (isEntering) {
1601
- if (this.jobber.busy && this.jobber.destroy) await this.jobber.destroy();
1602
- await this.jobber.add(() => this.#resolveBlock(hash));
1603
- } else {
1604
- await this.#resolveBlock(hash);
1605
- }
1606
- try {
1607
- const lastBlockHash = await globalThis.stateStore.get("lastBlock");
1608
- if (lastBlockHash === hash) {
1572
+ const resolution = Promise.resolve().then(async () => {
1573
+ for (let attempt = 0; attempt < 3; attempt++) {
1574
+ try {
1575
+ await this.#resolveBlock(hash);
1609
1576
  this.#resolveErrored = false;
1610
1577
  return;
1578
+ } catch (error) {
1579
+ console.error(`block resolution attempt ${attempt + 1} failed for ${hash}`, error);
1580
+ if (attempt === 2) {
1581
+ if (!this.wantList.includes(hash)) this.wantList.push(hash);
1582
+ throw new ResolveError(`block: ${hash}`, { cause: error });
1583
+ }
1611
1584
  }
1612
- } catch (error) {
1613
1585
  }
1614
- } catch (error) {
1615
- console.log({ error });
1616
- this.#resolveErrorCount += 1;
1617
- if (this.#resolveErrorCount < 3) {
1618
- this.#resolvingHashes.delete(hash);
1619
- return this.resolveBlock(hash);
1620
- }
1621
- this.#resolveErrorCount = 0;
1622
- this.wantList.push(hash);
1623
- throw new ResolveError(`block: ${hash}`, { cause: error });
1624
- } finally {
1586
+ }).finally(() => {
1625
1587
  this.#resolvingHashes.delete(hash);
1626
1588
  if (this.#resolvingHashes.size === 0) this.#resolving = false;
1627
- }
1589
+ });
1590
+ this.#resolvingHashes.set(hash, resolution);
1591
+ return resolution;
1628
1592
  }
1629
1593
  async resolveBlocks() {
1630
1594
  if (this.#chainSyncing || this.#resolving) {
@@ -1761,24 +1725,6 @@ class State extends Contract {
1761
1725
  return;
1762
1726
  }
1763
1727
  if (localStateHash !== remoteBlockHash) {
1764
- if (this.wantList.length > 0) {
1765
- debug$1(`Fetching ${this.wantList.length} blocks before resolving`);
1766
- const getBatch = async (batch) => {
1767
- const blocks2 = await Promise.all(
1768
- batch.map(
1769
- (hash) => this.getAndPutBlock(hash).catch((e) => {
1770
- console.warn(`failed to fetch block ${hash}`, e);
1771
- })
1772
- )
1773
- );
1774
- const transactions = blocks2.filter((block) => Boolean(block)).flatMap((block) => block.decoded.transactions);
1775
- return this.#resolveTransactions(transactions);
1776
- };
1777
- for (let i = 0; i < this.wantList.length; i += 50) {
1778
- const batch = this.wantList.slice(i, i + 50);
1779
- await getBatch(batch);
1780
- }
1781
- }
1782
1728
  debug$1(`Resolving remote block: ${remoteBlockHash} @${remoteIndex} (differs from local state)`);
1783
1729
  await this.resolveBlock(remoteBlockHash);
1784
1730
  const blocksSynced = remoteIndex - localIndex;
@@ -2134,15 +2080,6 @@ const validateBlockEconomics = (block, calculatedFees, validatorFees = /* @__PUR
2134
2080
  }
2135
2081
  };
2136
2082
 
2137
- const resolveTransactionReference = async (expectedHash, transactionData) => {
2138
- const transaction = transactionData instanceof TransactionMessage ? transactionData : new TransactionMessage(transactionData);
2139
- const actualHash = await transaction.hash();
2140
- if (actualHash !== expectedHash) {
2141
- throw new Error(`Transaction hash mismatch: expected ${expectedHash}, got ${actualHash}`);
2142
- }
2143
- return transaction;
2144
- };
2145
-
2146
2083
  const consensusSignableData = (validatorsAddress, type, message) => ({
2147
2084
  from: String(message.from),
2148
2085
  to: validatorsAddress,
@@ -3090,13 +3027,6 @@ class Chain extends VersionControl {
3090
3027
  }
3091
3028
  }
3092
3029
  }
3093
- if (this.wantList.length > 0) {
3094
- const promises = await Promise.allSettled(this.wantList.map((hash) => peernet.get(hash, "block")));
3095
- for (let i = promises.length - 1; i >= 0; i -= 1) {
3096
- if (promises[i].status === "fulfilled") this.wantList.splice(i, 1);
3097
- }
3098
- if (this.wantList.length === 0) await this.triggerSync();
3099
- }
3100
3030
  try {
3101
3031
  let stateInfo = await this.#makeRequest(peer, "stateInfo");
3102
3032
  if (stateInfo instanceof Uint8Array) {