@leofcoin/chain 1.10.10 → 1.10.11

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.
Files changed (44) hide show
  1. package/exports/beacon-envelope.js +68 -0
  2. package/exports/beacon-epoch.js +117 -0
  3. package/exports/beacon-lifecycle.js +155 -0
  4. package/exports/beacon-round.js +77 -0
  5. package/exports/beacon-wire.js +98 -0
  6. package/exports/beacon.js +141 -0
  7. package/exports/browser/beacon-envelope.js +163 -0
  8. package/exports/browser/beacon-epoch.js +116 -0
  9. package/exports/browser/beacon-lifecycle.js +154 -0
  10. package/exports/browser/beacon-round.js +76 -0
  11. package/exports/browser/beacon-wire.js +99 -0
  12. package/exports/browser/beacon.js +1706 -0
  13. package/exports/browser/{browser-D-r0O9Qn-BZDYY6cg.js → browser-CWeoyGUw-BabtHowB.js} +4 -2
  14. package/exports/browser/{browser-_hiyXwPp-DYI1tyUr.js → browser-DvU1xNFS-sdlKNCJc.js} +4 -2
  15. package/exports/browser/chain.js +110 -5053
  16. package/exports/browser/{client-BVhUamQG-D-D1e_x8.js → client-B-jyclOB-CsNYfj4Z.js} +6 -4
  17. package/exports/browser/constants-Cv0p224A.js +130 -0
  18. package/exports/browser/hkdf-DhdhLAAv.js +147 -0
  19. package/exports/browser/{index-BD0Anx7_-Dg4_tCeN.js → index-Bxr5Iztg-C6xBk0rK.js} +4 -2
  20. package/exports/browser/index-CvKt4UDE.js +464 -0
  21. package/exports/browser/index-D7FUx7Dd.js +4996 -0
  22. package/exports/browser/{messages-UKnuelZ7-DJT-98q-.js → messages-FMRAS8QX-CvlZBzy5.js} +4 -2
  23. package/exports/browser/{node-browser-DlzZ5CP_.js → node-browser-xlqSBOaN.js} +12 -5
  24. package/exports/browser/node-browser.js +4 -2
  25. package/exports/browser/{constants-gMYZLHKp.js → proposal.proto-BcUgd885.js} +61 -620
  26. package/exports/browser/quorum-S_qdgiAY.js +8 -0
  27. package/exports/browser/weierstrass-C-jX_jly.js +2156 -0
  28. package/exports/browser/workers/block-worker.js +1 -1
  29. package/exports/browser/workers/machine-worker.js +7052 -78
  30. package/exports/browser/workers/{worker-CZqErLI7-BxofVJAn.js → worker-DMCj1e6z-CTYVa2yX.js} +30 -1
  31. package/exports/chain.js +91 -47
  32. package/exports/{constants-D6gWzJZg.js → constants-CMYKv-Rt.js} +1 -1
  33. package/exports/node.js +1 -1
  34. package/exports/quorum-S_qdgiAY.js +8 -0
  35. package/exports/workers/block-worker.js +1 -1
  36. package/exports/workers/machine-worker.js +7052 -78
  37. package/exports/workers/{worker-CZqErLI7-BxofVJAn.js → worker-DMCj1e6z-CTYVa2yX.js} +30 -1
  38. package/package.json +29 -2
  39. package/types/beacon-envelope.d.ts +27 -0
  40. package/types/beacon-epoch.d.ts +28 -0
  41. package/types/beacon-lifecycle.d.ts +40 -0
  42. package/types/beacon-round.d.ts +18 -0
  43. package/types/beacon-wire.d.ts +31 -0
  44. package/types/beacon.d.ts +24 -0
@@ -7929,6 +7929,21 @@ const blockchainCodecs = [
7929
7929
  }
7930
7930
  ];
7931
7931
  const consensusCodecs = [
7932
+ {
7933
+ name: 'beacon-activation-message',
7934
+ codec: '0x62616d',
7935
+ hashAlg: 'keccak-256'
7936
+ },
7937
+ {
7938
+ name: 'beacon-commitment-message',
7939
+ codec: '0x62636d',
7940
+ hashAlg: 'keccak-256'
7941
+ },
7942
+ {
7943
+ name: 'beacon-share-message',
7944
+ codec: '0x62736d',
7945
+ hashAlg: 'keccak-256'
7946
+ },
7932
7947
  {
7933
7948
  name: 'proposal-message',
7934
7949
  codec: '0x70726d',
@@ -9053,6 +9068,20 @@ var proto$2 = {
9053
9068
  reward: BigInt(0)
9054
9069
  };
9055
9070
 
9071
+ ({
9072
+ epoch: BigInt(0)});
9073
+
9074
+ ({
9075
+ epoch: BigInt(0),
9076
+ threshold: BigInt(0),
9077
+ participant: BigInt(0),
9078
+ commitments: Array()});
9079
+
9080
+ ({
9081
+ epoch: BigInt(0),
9082
+ round: BigInt(0),
9083
+ participant: BigInt(0)});
9084
+
9056
9085
  var proto$1 = {
9057
9086
  creator: String(),
9058
9087
  contract: new Uint8Array(),
@@ -9207,4 +9236,4 @@ class EasyWorker {
9207
9236
  }
9208
9237
  }
9209
9238
 
9210
- export { EasyWorker as E, FormatInterface as F, index$2 as a, proto$2 as b, jsonStringifyBigInt$1 as c, proto$1 as d, proto as e, index$3 as i, jsonParseBigInt$1 as j, proto$3 as p };
9239
+ export { EasyWorker as E, FormatInterface as F, index$2 as a, proto$2 as b, jsonParseBigInt$1 as c, proto$1 as d, proto as e, index$3 as i, jsonStringifyBigInt$1 as j, proto$3 as p };
package/exports/chain.js CHANGED
@@ -3,14 +3,15 @@ import { Codec } from '@leofcoin/codec-format-interface';
3
3
  import { jsonStringifyBigInt, jsonParseBigInt, formatBytes, parseUnits, formatUnits } from '@leofcoin/utils';
4
4
  import { TransactionMessage, BlockMessage, ContractMessage, LastBlockMessage, PrevoteMessage, PrecommitMessage, ProposalMessage, BWMessage, StateMessage } from '@leofcoin/messages';
5
5
  import addresses, { contractFactory, nativeToken } from '@leofcoin/addresses';
6
- import { MAX_TRANSACTION_BYTES, MAX_BLOCK_TRANSACTION_BYTES, MAX_BLOCK_TRANSACTIONS, createTransactionHash, calculateFee, createContractMessage, signTransaction, distributeTransactionFee, supportsTransactionFees, supportsMonetaryPolicy, validateBlockResourceLimits, calculateMonetaryPolicy, distributeAmount, aggregateValidatorFees, contractFactoryMessage, nativeTokenMessage, validatorsMessage, nameServiceMessage } from '@leofcoin/lib';
6
+ import { MAX_TRANSACTION_BYTES, MAX_BLOCK_TRANSACTION_BYTES, MAX_BLOCK_TRANSACTIONS, createTransactionHash, calculateFee, createContractMessage, signTransaction, distributeTransactionFee, supportsTransactionFees, supportsMonetaryPolicy, validateBlockResourceLimits, calculateMonetaryPolicy, distributeAmount, aggregateValidatorFees, MONETARY_POLICY_AUTHORITY, contractFactoryMessage, nativeTokenMessage, validatorsMessage, nameServiceMessage } from '@leofcoin/lib';
7
7
  import MultiWallet from '@leofcoin/multi-wallet';
8
8
  import { fromBase58 } from '@vandeurenglenn/typed-array-utils';
9
9
  import semver from 'semver';
10
10
  import { randombytes } from '@leofcoin/crypto';
11
11
  import EasyWorker from '@vandeurenglenn/easy-worker';
12
12
  import { ContractDeploymentError, ExecutionError, isResolveError, ResolveError, isExecutionError } from '@leofcoin/errors';
13
- import { P as PROTOCOL_VERSION, R as REACHED_ONE_ZERO_ZERO } from './constants-D6gWzJZg.js';
13
+ import { P as PROTOCOL_VERSION, R as REACHED_ONE_ZERO_ZERO } from './constants-CMYKv-Rt.js';
14
+ import { q as quorumThreshold } from './quorum-S_qdgiAY.js';
14
15
  import '@leofcoin/networks';
15
16
 
16
17
  const limit = 1800;
@@ -891,7 +892,7 @@ class Machine {
891
892
  * @param {Array} parameters
892
893
  * @returns Promise<message>
893
894
  */
894
- async execute(contract, method, parameters, sender) {
895
+ async execute(contract, method, parameters, sender, execution) {
895
896
  try {
896
897
  if (contract === contractFactory && method === "registerContract") {
897
898
  if (await this.has(parameters[0])) throw new Error(`duplicate contract @${parameters[0]}`);
@@ -933,7 +934,10 @@ ${error.message}`);
933
934
  contract,
934
935
  method,
935
936
  params: parameters,
936
- sender
937
+ sender,
938
+ executionSeed: execution?.seed,
939
+ executionTimestamp: execution?.timestamp,
940
+ executionRandomness: execution?.randomness
937
941
  }
938
942
  });
939
943
  });
@@ -1445,7 +1449,8 @@ class State extends Contract {
1445
1449
  if (!(block instanceof Uint8Array)) block = new Uint8Array(Object.values(block));
1446
1450
  block = await new BlockMessage(block);
1447
1451
  const resolvedHash = await block.hash();
1448
- if (resolvedHash !== hash) throw new ResolveError(`block hash mismatch: requested ${hash}, received ${resolvedHash}`);
1452
+ if (resolvedHash !== hash)
1453
+ throw new ResolveError(`block hash mismatch: requested ${hash}, received ${resolvedHash}`);
1449
1454
  const { index } = block.decoded;
1450
1455
  if (this.#blocks[index] && this.#blocks[index].hash !== resolvedHash) {
1451
1456
  throw new ResolveError(`conflicting block ${resolvedHash} @${index}`);
@@ -1787,7 +1792,7 @@ class State extends Contract {
1787
1792
  #loadBlockTransactions;
1788
1793
  #getLastTransactions;
1789
1794
  // todo throw error
1790
- async #_executeTransaction(transaction, validators, feesEnabled, burnBasisPoints) {
1795
+ async #_executeTransaction(transaction, validators, feesEnabled, burnBasisPoints, blockTimestamp) {
1791
1796
  try {
1792
1797
  const hash = await transaction.hash();
1793
1798
  if (feesEnabled) {
@@ -1799,7 +1804,8 @@ class State extends Contract {
1799
1804
  transaction.decoded.to,
1800
1805
  transaction.decoded.method,
1801
1806
  transaction.decoded.params,
1802
- transaction.decoded.from
1807
+ transaction.decoded.from,
1808
+ { seed: hash, timestamp: Number(blockTimestamp) }
1803
1809
  );
1804
1810
  } catch (error) {
1805
1811
  console.log(error);
@@ -1850,7 +1856,13 @@ class State extends Contract {
1850
1856
  BigInt(await this.#machine.get(nativeToken, "targetSupply"))
1851
1857
  ) : { subsidy: 0n, burnBasisPoints: 1000n };
1852
1858
  for (const transaction of transactions) {
1853
- await this.#_executeTransaction(transaction, validators, feesEnabled, policy.burnBasisPoints);
1859
+ await this.#_executeTransaction(
1860
+ transaction,
1861
+ validators,
1862
+ feesEnabled,
1863
+ policy.burnBasisPoints,
1864
+ block.timestamp
1865
+ );
1854
1866
  }
1855
1867
  if (monetaryPolicyEnabled && policy.subsidy > 0n) {
1856
1868
  await this.#machine.settleRewards([
@@ -2272,13 +2284,6 @@ class ConnectionMonitor {
2272
2284
  }
2273
2285
  }
2274
2286
 
2275
- const quorumThreshold = (validatorCount) => {
2276
- if (!Number.isSafeInteger(validatorCount) || validatorCount < 1) {
2277
- throw new Error("validator count must be a positive safe integer");
2278
- }
2279
- return Math.floor(2 * validatorCount / 3) + 1;
2280
- };
2281
-
2282
2287
  const validateChainLink = (localTip, incoming) => {
2283
2288
  const localHash = localTip?.hash || "0x0";
2284
2289
  const localIndex = Number(localTip?.index ?? -1);
@@ -2377,6 +2382,14 @@ const proposalDelay = ({
2377
2382
  return Math.max(0, Math.max(nextFromCanonicalBlock, nextFromLocalAttempt) - now);
2378
2383
  };
2379
2384
 
2385
+ const enqueueTransaction = async (transaction, ops) => {
2386
+ const hash = await transaction.hash();
2387
+ if (!await ops.hasInPool(hash) && !await ops.hasInStore(hash)) {
2388
+ await ops.putToPool(hash, transaction.encoded);
2389
+ }
2390
+ ops.addPendingNonce(transaction.decoded.from, transaction.decoded.nonce);
2391
+ return hash;
2392
+ };
2380
2393
  const compareTransactionNonces = (left, right) => {
2381
2394
  const leftNonce = BigInt(left ?? 0);
2382
2395
  const rightNonce = BigInt(right ?? 0);
@@ -2627,9 +2640,7 @@ class Chain extends VersionControl {
2627
2640
  };
2628
2641
  // ─────────────────────────────────────────────────────────────────────────
2629
2642
  this.#addTransaction = async (message) => {
2630
- const transaction = new TransactionMessage(message);
2631
- const hash = await transaction.hash();
2632
- this.addPendingNonce(transaction.decoded.from, transaction.decoded.nonce);
2643
+ const hash = await this.#sendTransaction(message);
2633
2644
  debug(`added ${hash}`);
2634
2645
  };
2635
2646
  this.#init();
@@ -2704,12 +2715,7 @@ class Chain extends VersionControl {
2704
2715
  return signConsensusMessage(addresses.validators, type, message, identity);
2705
2716
  }
2706
2717
  async #verifyConsensusMessage(type, message) {
2707
- return verifyConsensusMessage(
2708
- addresses.validators,
2709
- type,
2710
- message,
2711
- globalThis.peernet?.network || "leofcoin"
2712
- );
2718
+ return verifyConsensusMessage(addresses.validators, type, message, globalThis.peernet?.network || "leofcoin");
2713
2719
  }
2714
2720
  async #getConsensusValidators(nextBlockIndex2) {
2715
2721
  const localBlock = await this.lastBlock;
@@ -2793,7 +2799,10 @@ class Chain extends VersionControl {
2793
2799
  const adaptivePolicy = supportsMonetaryPolicy(blockMessage.decoded.protocolVersion);
2794
2800
  if (adaptivePolicy) await validateBlockResourceLimits(transactions);
2795
2801
  const policy = await this.#monetaryPolicy(blockMessage.decoded.protocolVersion);
2796
- const calculatedFees = feesEnabled ? (await Promise.all(transactions.map((transaction) => calculateFee(transaction.decoded)))).reduce((total, fee) => total + BigInt(fee), 0n) : 0n;
2802
+ const calculatedFees = feesEnabled ? (await Promise.all(transactions.map((transaction) => calculateFee(transaction.decoded)))).reduce(
2803
+ (total, fee) => total + BigInt(fee),
2804
+ 0n
2805
+ ) : 0n;
2797
2806
  const feeEntries = feesEnabled ? await Promise.all(
2798
2807
  transactions.map(async (transaction) => ({
2799
2808
  fee: BigInt(await calculateFee(transaction.decoded)),
@@ -2802,7 +2811,11 @@ class Chain extends VersionControl {
2802
2811
  ) : [];
2803
2812
  const validatorAddresses = blockMessage.decoded.validators.map(({ address }) => address);
2804
2813
  const validatorFees = feesEnabled ? aggregateValidatorFees(feeEntries, validatorAddresses, policy.burnBasisPoints) : new Map(validatorAddresses.map((address) => [address, 0n]));
2805
- const subsidyRewards = adaptivePolicy ? distributeAmount(policy.subsidy, validatorAddresses, Number(blockMessage.decoded.index) % validatorAddresses.length) : new Map(validatorAddresses.map((address) => [address, policy.subsidy / BigInt(validatorAddresses.length)]));
2814
+ const subsidyRewards = adaptivePolicy ? distributeAmount(
2815
+ policy.subsidy,
2816
+ validatorAddresses,
2817
+ Number(blockMessage.decoded.index) % validatorAddresses.length
2818
+ ) : new Map(validatorAddresses.map((address) => [address, policy.subsidy / BigInt(validatorAddresses.length)]));
2806
2819
  validateBlockEconomics(blockMessage.decoded, calculatedFees, validatorFees, subsidyRewards, policy.subsidy);
2807
2820
  if (feesEnabled) {
2808
2821
  const feesBySender = /* @__PURE__ */ new Map();
@@ -2814,7 +2827,9 @@ class Chain extends VersionControl {
2814
2827
  [...feesBySender].map(async ([sender, required]) => {
2815
2828
  const balance = BigInt(await this.balanceOf(sender) || 0n);
2816
2829
  if (balance < required) {
2817
- throw new Error(`insufficient balance for transaction fees from ${sender}: need ${required}, got ${balance}`);
2830
+ throw new Error(
2831
+ `insufficient balance for transaction fees from ${sender}: need ${required}, got ${balance}`
2832
+ );
2818
2833
  }
2819
2834
  })
2820
2835
  );
@@ -2822,10 +2837,9 @@ class Chain extends VersionControl {
2822
2837
  return transactions;
2823
2838
  }
2824
2839
  async #assertFeeBurnSupported(protocolVersion) {
2825
- const creator = await this.staticCall(addresses.nativeToken, "creator");
2826
2840
  const [canBurn, canMint] = await Promise.all([
2827
- this.staticCall(addresses.nativeToken, "hasRole", [creator, "BURN"]),
2828
- this.staticCall(addresses.nativeToken, "hasRole", [creator, "MINT"])
2841
+ this.staticCall(addresses.nativeToken, "hasRole", [MONETARY_POLICY_AUTHORITY, "BURN"]),
2842
+ this.staticCall(addresses.nativeToken, "hasRole", [MONETARY_POLICY_AUTHORITY, "MINT"])
2829
2843
  ]);
2830
2844
  if (!canBurn || supportsMonetaryPolicy(protocolVersion) && !canMint) {
2831
2845
  throw new Error("native token genesis does not support protocol monetary policy");
@@ -3287,12 +3301,24 @@ class Chain extends VersionControl {
3287
3301
  async #versionHandler() {
3288
3302
  return new globalThis.peernet.protos["peernet-response"]({ response: this.version });
3289
3303
  }
3290
- async #executeTransaction({ hash, from, to, method, params, nonce, feePayments = { payments: [], burned: 0n } }) {
3304
+ async #executeTransaction({
3305
+ hash,
3306
+ from,
3307
+ to,
3308
+ method,
3309
+ params,
3310
+ nonce,
3311
+ executionTimestamp,
3312
+ feePayments = { payments: [], burned: 0n }
3313
+ }) {
3291
3314
  try {
3292
3315
  if (feePayments.payments.length > 0 || feePayments.burned > 0n) {
3293
3316
  await this.machine.collectFee(from, feePayments.payments, feePayments.burned);
3294
3317
  }
3295
- let result = await this.machine.execute(to, method, params, from);
3318
+ let result = await this.machine.execute(to, method, params, from, {
3319
+ seed: hash,
3320
+ timestamp: Number(executionTimestamp)
3321
+ });
3296
3322
  globalThis.pubsub.publish(`transaction.completed.${hash}`, { status: "fulfilled", hash });
3297
3323
  return result || "no state change";
3298
3324
  } catch (error) {
@@ -3367,12 +3393,19 @@ class Chain extends VersionControl {
3367
3393
  this.removePendingNonce(transaction.decoded.from, transaction.decoded.nonce);
3368
3394
  const transactionHash = await transaction.hash();
3369
3395
  const validatorAddresses = blockMessage.decoded.validators.map(({ address }) => address);
3370
- const feeDistribution = supportsTransactionFees(blockMessage.decoded.protocolVersion) ? distributeTransactionFee(BigInt(await calculateFee(transaction.decoded)), transactionHash, validatorAddresses, monetaryPolicy.burnBasisPoints) : { payments: [], burned: 0n };
3371
- await this.#handleTransaction(transaction, [], void 0, feeDistribution);
3396
+ const feeDistribution = supportsTransactionFees(blockMessage.decoded.protocolVersion) ? distributeTransactionFee(
3397
+ BigInt(await calculateFee(transaction.decoded)),
3398
+ transactionHash,
3399
+ validatorAddresses,
3400
+ monetaryPolicy.burnBasisPoints
3401
+ ) : { payments: [], burned: 0n };
3402
+ await this.#handleTransaction(transaction, [], blockMessage.decoded, feeDistribution);
3372
3403
  }
3373
3404
  if (supportsMonetaryPolicy(blockMessage.decoded.protocolVersion) && monetaryPolicy.subsidy > 0n) {
3374
3405
  const validators = blockMessage.decoded.validators.map(({ address }) => address);
3375
- await this.machine.settleRewards([...distributeAmount(monetaryPolicy.subsidy, validators, blockIndex % validators.length)]);
3406
+ await this.machine.settleRewards([
3407
+ ...distributeAmount(monetaryPolicy.subsidy, validators, blockIndex % validators.length)
3408
+ ]);
3376
3409
  }
3377
3410
  try {
3378
3411
  promises = await Promise.allSettled(promises);
@@ -3442,7 +3475,12 @@ class Chain extends VersionControl {
3442
3475
  return;
3443
3476
  }
3444
3477
  try {
3445
- const result = await this.#executeTransaction({ ...transaction.decoded, hash, feePayments });
3478
+ const result = await this.#executeTransaction({
3479
+ ...transaction.decoded,
3480
+ hash,
3481
+ executionTimestamp: block?.timestamp ?? transaction.decoded.timestamp,
3482
+ feePayments
3483
+ });
3446
3484
  if (block) {
3447
3485
  block.transactions.push(hash);
3448
3486
  block.fees = block.fees += await calculateFee(transaction.decoded);
@@ -3502,7 +3540,8 @@ class Chain extends VersionControl {
3502
3540
  await globalThis.transactionPoolStore.delete(hash);
3503
3541
  continue;
3504
3542
  }
3505
- if (block.transactions.length >= MAX_BLOCK_TRANSACTIONS || blockTransactionBytes + transactionBytes > MAX_BLOCK_TRANSACTION_BYTES) break;
3543
+ if (block.transactions.length >= MAX_BLOCK_TRANSACTIONS || blockTransactionBytes + transactionBytes > MAX_BLOCK_TRANSACTION_BYTES)
3544
+ break;
3506
3545
  await this.validateTransactionSignature(transaction);
3507
3546
  block.transactions.push(hash);
3508
3547
  blockTransactionBytes += transactionBytes;
@@ -3592,18 +3631,23 @@ class Chain extends VersionControl {
3592
3631
  async #sendTransaction(transaction) {
3593
3632
  transaction = await new TransactionMessage(transaction.encoded || transaction);
3594
3633
  await this.validateTransactionSignature(transaction);
3595
- const hash = await transaction.hash();
3634
+ let hash;
3596
3635
  try {
3597
- const has = await globalThis.transactionPoolStore.has(hash);
3598
- if (!has && !await transactionStore.has(hash)) {
3599
- await globalThis.transactionPoolStore.put(hash, transaction.encoded);
3600
- }
3636
+ hash = await enqueueTransaction(transaction, {
3637
+ putToPool: (txHash, data) => globalThis.transactionPoolStore.put(txHash, data),
3638
+ hasInPool: (txHash) => globalThis.transactionPoolStore.has(txHash),
3639
+ hasInStore: (txHash) => globalThis.transactionStore.has(txHash),
3640
+ addPendingNonce: (address, nonce) => this.addPendingNonce(address, nonce)
3641
+ });
3601
3642
  if (this.#participating && !this.#runningEpoch) this.#runEpoch();
3643
+ return hash;
3602
3644
  } catch (e) {
3603
- try {
3604
- globalThis.peernet.publish("invalid-transaction", hash);
3605
- } catch (publishError) {
3606
- debug("peernet publish failed: invalid-transaction", publishError?.message ?? publishError);
3645
+ if (hash) {
3646
+ try {
3647
+ globalThis.peernet.publish("invalid-transaction", hash);
3648
+ } catch (publishError) {
3649
+ debug("peernet publish failed: invalid-transaction", publishError?.message ?? publishError);
3650
+ }
3607
3651
  }
3608
3652
  throw new Error("invalid transaction");
3609
3653
  }
@@ -3616,7 +3660,7 @@ class Chain extends VersionControl {
3616
3660
  async sendTransaction(transaction) {
3617
3661
  const transactionMessage = await new TransactionMessage({ ...transaction });
3618
3662
  const event = await super.sendTransaction(transactionMessage);
3619
- this.#sendTransaction(transactionMessage.encoded);
3663
+ await this.#sendTransaction(transactionMessage.encoded);
3620
3664
  try {
3621
3665
  globalThis.peernet.publish("send-transaction", transactionMessage.encoded);
3622
3666
  } catch (publishError) {
@@ -1,6 +1,6 @@
1
1
  import networks from '@leofcoin/networks';
2
2
 
3
- const PROTOCOL_VERSION = "0.2.0";
3
+ const PROTOCOL_VERSION = "0.3.0";
4
4
  const REACHED_ONE_ZERO_ZERO = false;
5
5
  const DEFAULT_NODE_OPTIONS = {
6
6
  autoStart: false,
package/exports/node.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import Peernet from '@leofcoin/peernet';
2
2
  import nodeConfig from '@leofcoin/lib/node-config';
3
- import { D as DEFAULT_NODE_OPTIONS } from './constants-D6gWzJZg.js';
3
+ import { D as DEFAULT_NODE_OPTIONS } from './constants-CMYKv-Rt.js';
4
4
  import '@leofcoin/networks';
5
5
 
6
6
  class Node {
@@ -0,0 +1,8 @@
1
+ const quorumThreshold = (validatorCount) => {
2
+ if (!Number.isSafeInteger(validatorCount) || validatorCount < 1) {
3
+ throw new Error("validator count must be a positive safe integer");
4
+ }
5
+ return Math.floor(2 * validatorCount / 3) + 1;
6
+ };
7
+
8
+ export { quorumThreshold as q };
@@ -1,4 +1,4 @@
1
- import { E as EasyWorker, F as FormatInterface, p as proto$3, i as index$3, a as index$2, b as proto$2 } from './worker-CZqErLI7-BxofVJAn.js';
1
+ import { E as EasyWorker, F as FormatInterface, p as proto$3, i as index$3, a as index$2, b as proto$2 } from './worker-DMCj1e6z-CTYVa2yX.js';
2
2
 
3
3
  class ValidatorMessage extends FormatInterface {
4
4
  get messageName() {