@xyo-network/chain-services 1.4.0 → 1.4.2

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.
@@ -252,8 +252,9 @@ var BaseEthProvider = class {
252
252
  };
253
253
 
254
254
  // src/BlockProducer/XyoBlockProducer.ts
255
- import { assertEx as assertEx2 } from "@xylabs/assert";
256
- import { toHex as toHex2 } from "@xylabs/hex";
255
+ import { assertEx as assertEx3 } from "@xylabs/assert";
256
+ import { exists } from "@xylabs/exists";
257
+ import { hexToBigInt, toHex as toHex2 } from "@xylabs/hex";
257
258
  import { isUndefined } from "@xylabs/typeof";
258
259
  import { FixedPercentageBlockRewardDiviner, FixedPercentageBlockRewardDivinerConfigSchema } from "@xyo-network/chain-modules";
259
260
  import { buildBlock } from "@xyo-network/chain-protocol";
@@ -261,35 +262,40 @@ import { PayloadBuilder } from "@xyo-network/payload-builder";
261
262
  import { asBlockBoundWitness, BlockNumberSchema, ChainStakeIntentSchema } from "@xyo-network/xl1-protocol";
262
263
 
263
264
  // src/BlockProducer/generateTransactionTransfers.ts
265
+ import { assertEx as assertEx2 } from "@xylabs/assert";
264
266
  import { hexFromBigInt } from "@xylabs/hex";
267
+ import { XYO_ZERO_ADDRESS } from "@xyo-network/chain-utils";
265
268
  import { HydratedTransactionWrapper } from "@xyo-network/chain-wrappers";
266
- import { TransferSchema } from "@xyo-network/xl1-protocol";
269
+ import { MicroXL1, mXL1ToXL1, TransferSchema, XL1 } from "@xyo-network/xl1-protocol";
270
+ import { transactionRequiredGas } from "@xyo-network/xl1-protocol-sdk";
267
271
  async function generateTransactionTransfers(address, transactions) {
268
272
  const txs = await Promise.all(transactions.map((tx) => HydratedTransactionWrapper.parse(tx)));
269
- const txCosts = [];
273
+ const txBaseFeeCosts = {};
270
274
  for (const tx of txs) {
271
- const existingItem = txCosts.find(([addr]) => addr === tx.boundWitness.from);
272
- if (existingItem) {
273
- existingItem[1] += tx.fees.base;
274
- } else {
275
- txCosts.push([
276
- tx.boundWitness.from,
277
- tx.fees.base
278
- ]);
279
- }
275
+ txBaseFeeCosts[tx.boundWitness.from] = XL1((txBaseFeeCosts[tx.boundWitness.from] ?? 0n) + mXL1ToXL1(tx.fees.base));
276
+ }
277
+ const txGasCosts = {};
278
+ for (const tx of txs) {
279
+ const requiredGas = transactionRequiredGas(tx.data);
280
+ const totalGasCostInMicroXL1 = MicroXL1(requiredGas * tx.fees.gasPrice);
281
+ txGasCosts[tx.boundWitness.from] = XL1((txBaseFeeCosts[tx.boundWitness.from] ?? 0n) + mXL1ToXL1(totalGasCostInMicroXL1));
280
282
  }
281
- const payloads = txCosts.map(([from, amount]) => {
283
+ const payloads = Object.entries(txBaseFeeCosts).map(([from, amount]) => {
282
284
  const payload = {
283
285
  schema: TransferSchema,
284
286
  epoch: Date.now(),
285
287
  from,
286
- // TODO: add function to Wrapper to calculate entire cost of transaction
287
288
  transfers: {
288
- [address]: hexFromBigInt(amount)
289
+ // burn the base fee
290
+ [XYO_ZERO_ADDRESS]: hexFromBigInt(amount)
289
291
  }
290
292
  };
291
293
  return payload;
292
294
  });
295
+ for (const [from, amount] of Object.entries(txGasCosts)) {
296
+ const fromPayload = assertEx2(payloads.find((p) => p.from === from), () => "from payload not found");
297
+ fromPayload.transfers[address] = hexFromBigInt(amount);
298
+ }
293
299
  return payloads;
294
300
  }
295
301
  __name(generateTransactionTransfers, "generateTransactionTransfers");
@@ -317,37 +323,40 @@ var XyoBlockProducer = class _XyoBlockProducer extends BaseService {
317
323
  return this.account.address;
318
324
  }
319
325
  get account() {
320
- return assertEx2(this.params.account, () => "account is required");
326
+ return assertEx3(this.params.account, () => "account is required");
327
+ }
328
+ get accountBalanceService() {
329
+ return assertEx3(this.params.accountBalanceService, () => "accountBalanceService is required");
321
330
  }
322
331
  get chainFinalizedArchivist() {
323
- return assertEx2(this.params.chainFinalizedArchivist, () => "chainFinalizedArchivist is required");
332
+ return assertEx3(this.params.chainFinalizedArchivist, () => "chainFinalizedArchivist is required");
324
333
  }
325
334
  get chainInfo() {
326
- return assertEx2(this.params.chainInformation, () => "chainInfo is required");
335
+ return assertEx3(this.params.chainInformation, () => "chainInfo is required");
327
336
  }
328
337
  get electionService() {
329
- return assertEx2(this.params.electionService, () => "electionService is required");
338
+ return assertEx3(this.params.electionService, () => "electionService is required");
330
339
  }
331
340
  get pendingTransactions() {
332
- return assertEx2(this.params.pendingTransactions, () => "pendingTransactions is required");
341
+ return assertEx3(this.params.pendingTransactions, () => "pendingTransactions is required");
333
342
  }
334
343
  get pendingTransactionsService() {
335
- return assertEx2(this.params.pendingTransactionsService, () => "Missing pendingTransactionsService");
344
+ return assertEx3(this.params.pendingTransactionsService, () => "Missing pendingTransactionsService");
336
345
  }
337
346
  get rejectedTransactionsArchivist() {
338
- return assertEx2(this.params.rejectedTransactionsArchivist, () => "No rejected transactions archivist");
347
+ return assertEx3(this.params.rejectedTransactionsArchivist, () => "No rejected transactions archivist");
339
348
  }
340
349
  get rewardAddress() {
341
- return assertEx2(this.params.rewardAddress, () => "No reward address provided");
350
+ return assertEx3(this.params.rewardAddress, () => "No reward address provided");
342
351
  }
343
352
  get rewardService() {
344
- return assertEx2(this.params.rewardService, () => "rewardService is required");
353
+ return assertEx3(this.params.rewardService, () => "rewardService is required");
345
354
  }
346
355
  get stakeIntentService() {
347
- return assertEx2(this.params.stakeIntentService, () => "No StakeIntentService provided");
356
+ return assertEx3(this.params.stakeIntentService, () => "No StakeIntentService provided");
348
357
  }
349
358
  get validateHydratedBlockState() {
350
- return assertEx2(this.params.validateHydratedBlockState, () => "validateHydratedBlockState is required");
359
+ return assertEx3(this.params.validateHydratedBlockState, () => "validateHydratedBlockState is required");
351
360
  }
352
361
  async next(head) {
353
362
  if (head.chain !== this.chainInfo.id) return;
@@ -362,12 +371,12 @@ var XyoBlockProducer = class _XyoBlockProducer extends BaseService {
362
371
  blockRewardService: this.rewardService,
363
372
  config: {
364
373
  rewardAddress: this.rewardAddress,
365
- rewardPercentageRatio: 0,
374
+ rewardPercentageRatio: 50,
366
375
  schema: FixedPercentageBlockRewardDivinerConfigSchema
367
376
  }
368
377
  });
369
378
  }
370
- const blockHex = assertEx2(toHex2(block), () => "Failed to convert block to hex");
379
+ const blockHex = assertEx3(toHex2(block), () => "Failed to convert block to hex");
371
380
  const blockId = new PayloadBuilder({
372
381
  schema: BlockNumberSchema
373
382
  }).fields({
@@ -406,7 +415,7 @@ var XyoBlockProducer = class _XyoBlockProducer extends BaseService {
406
415
  }
407
416
  async proposeNextValidBlock(head) {
408
417
  return await this.spanAsync("proposeNextValidBlock", async () => {
409
- const { block: previousBlock } = assertEx2(asBlockBoundWitness(head), () => "Invalid head block");
418
+ const { block: previousBlock } = assertEx3(asBlockBoundWitness(head), () => "Invalid head block");
410
419
  const nextBlock = previousBlock + 1;
411
420
  const nextBlockTransactions = await this.pendingTransactionsService.getPendingTransactions(head._hash, _XyoBlockProducer.DefaultBlockSize);
412
421
  const blockPayloads = [];
@@ -416,8 +425,18 @@ var XyoBlockProducer = class _XyoBlockProducer extends BaseService {
416
425
  const rewardTransferPayload = await this.getBlockRewardTransfer(nextBlock);
417
426
  if (rewardTransferPayload) blockPayloads.push(rewardTransferPayload);
418
427
  const transactionTransfers = await generateTransactionTransfers(this.address, nextBlockTransactions);
419
- blockPayloads.push(...transactionTransfers);
420
- const block = await buildBlock(head, nextBlockTransactions, blockPayloads, [
428
+ const fundedTransfers = [];
429
+ const fundedNextBlockTransactions = nextBlockTransactions.map((tx) => {
430
+ const transfer = transactionTransfers.find((txTransfer) => txTransfer.from === tx[0].from);
431
+ if (!transfer) return;
432
+ const totalTransferCost = Object.values(transfer?.transfers).reduce((acc, t) => acc + hexToBigInt(t), 0n);
433
+ if (hexToBigInt(this.accountBalanceService.getBalance(this.address)) >= totalTransferCost) {
434
+ fundedTransfers.push(transfer);
435
+ return tx;
436
+ }
437
+ }).filter(exists);
438
+ blockPayloads.push(...fundedTransfers);
439
+ const block = await buildBlock(head, fundedNextBlockTransactions, blockPayloads, [
421
440
  this.account
422
441
  ]);
423
442
  console.log("buildBlock", block);
@@ -437,7 +456,7 @@ XyoBlockProducer = _ts_decorate2([
437
456
  ], XyoBlockProducer);
438
457
 
439
458
  // src/BlockReward/EvmBlockRewardService.ts
440
- import { assertEx as assertEx3 } from "@xylabs/assert";
459
+ import { assertEx as assertEx4 } from "@xylabs/assert";
441
460
  import { XyoChainRewards__factory as XyoChainRewardsFactory } from "@xyo-network/typechain";
442
461
  import { toEthAddress } from "@xyo-network/xl1-protocol";
443
462
  function _ts_decorate3(decorators, target, key, desc) {
@@ -453,13 +472,13 @@ var EvmBlockRewardService = class extends BaseService {
453
472
  }
454
473
  _contractAddress;
455
474
  get chainService() {
456
- return assertEx3(this.params.chainService, () => "chainService is required");
475
+ return assertEx4(this.params.chainService, () => "chainService is required");
457
476
  }
458
477
  get contractAddress() {
459
- return assertEx3(this._contractAddress, () => "contractAddress is required");
478
+ return assertEx4(this._contractAddress, () => "contractAddress is required");
460
479
  }
461
480
  get provider() {
462
- return assertEx3(this.params.provider, () => "provider is required");
481
+ return assertEx4(this.params.provider, () => "provider is required");
463
482
  }
464
483
  async createHandler() {
465
484
  await super.createHandler();
@@ -475,7 +494,7 @@ EvmBlockRewardService = _ts_decorate3([
475
494
  ], EvmBlockRewardService);
476
495
 
477
496
  // src/BlockReward/XyoBlockRewardService.ts
478
- import { assertEx as assertEx4 } from "@xylabs/assert";
497
+ import { assertEx as assertEx5 } from "@xylabs/assert";
479
498
  import { toFixedPoint } from "@xylabs/decimal-precision";
480
499
  import { rewardFromBlockNumber } from "@xyo-network/chain-protocol";
481
500
  function _ts_decorate4(decorators, target, key, desc) {
@@ -505,22 +524,22 @@ var XyoBlockRewardService = class extends BaseService {
505
524
  });
506
525
  }
507
526
  get creatorReward() {
508
- return assertEx4(this.params.creatorReward, () => "creatorReward is required");
527
+ return assertEx5(this.params.creatorReward, () => "creatorReward is required");
509
528
  }
510
529
  get initialReward() {
511
- return assertEx4(this.params.initialStepReward, () => "initialStepReward is required");
530
+ return assertEx5(this.params.initialStepReward, () => "initialStepReward is required");
512
531
  }
513
532
  get minRewardPerBlock() {
514
- return assertEx4(this.params.minRewardPerBlock, () => "minRewardPerBlock is required");
533
+ return assertEx5(this.params.minRewardPerBlock, () => "minRewardPerBlock is required");
515
534
  }
516
535
  get stepFactorDenominator() {
517
- return assertEx4(this.params.stepFactorDenominator, () => "stepFactorDenominator is required");
536
+ return assertEx5(this.params.stepFactorDenominator, () => "stepFactorDenominator is required");
518
537
  }
519
538
  get stepFactorNumerator() {
520
- return assertEx4(this.params.stepFactorNumerator, () => "stepFactorNumerator is required");
539
+ return assertEx5(this.params.stepFactorNumerator, () => "stepFactorNumerator is required");
521
540
  }
522
541
  get stepSize() {
523
- return assertEx4(this.params.stepSize, () => "stepSize is required");
542
+ return assertEx5(this.params.stepSize, () => "stepSize is required");
524
543
  }
525
544
  getRewardForBlock(blockNumber) {
526
545
  return this.rewardFromBlockNumber(blockNumber, this.initialReward, this.stepSize, this.stepFactorNumerator, this.stepFactorDenominator, this.minRewardPerBlock, this.creatorReward);
@@ -535,7 +554,7 @@ XyoBlockRewardService = _ts_decorate4([
535
554
  ], XyoBlockRewardService);
536
555
 
537
556
  // src/ChainValidator/XyoValidator.ts
538
- import { assertEx as assertEx5 } from "@xylabs/assert";
557
+ import { assertEx as assertEx6 } from "@xylabs/assert";
539
558
  import { PayloadBuilder as PayloadBuilder2 } from "@xyo-network/payload-builder";
540
559
  function _ts_decorate5(decorators, target, key, desc) {
541
560
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -558,22 +577,22 @@ var XyoValidator = class extends BaseService {
558
577
  return this.account.address;
559
578
  }
560
579
  get account() {
561
- return assertEx5(this.params.account, () => "account is required");
580
+ return assertEx6(this.params.account, () => "account is required");
562
581
  }
563
582
  get chainFinalizedArchivist() {
564
- return assertEx5(this.params.chainFinalizedArchivist, () => "chainFinalizedArchivist is required");
583
+ return assertEx6(this.params.chainFinalizedArchivist, () => "chainFinalizedArchivist is required");
565
584
  }
566
585
  get chainInfo() {
567
- return assertEx5(this.params.chainInformation, () => "chainInfo is required");
586
+ return assertEx6(this.params.chainInformation, () => "chainInfo is required");
568
587
  }
569
588
  get electionService() {
570
- return assertEx5(this.params.electionService, () => "electionService is required");
589
+ return assertEx6(this.params.electionService, () => "electionService is required");
571
590
  }
572
591
  get pendingTransactions() {
573
- return assertEx5(this.params.pendingTransactions, () => "pendingTransactions is required");
592
+ return assertEx6(this.params.pendingTransactions, () => "pendingTransactions is required");
574
593
  }
575
594
  get rewardService() {
576
- return assertEx5(this.params.rewardService, () => "rewardService is required");
595
+ return assertEx6(this.params.rewardService, () => "rewardService is required");
577
596
  }
578
597
  validatePendingBlock(_block) {
579
598
  return [];
@@ -592,7 +611,7 @@ XyoValidator = _ts_decorate5([
592
611
  ], XyoValidator);
593
612
 
594
613
  // src/Election/XyoElectionService.ts
595
- import { assertEx as assertEx6 } from "@xylabs/assert";
614
+ import { assertEx as assertEx7 } from "@xylabs/assert";
596
615
  import { hexToLast4BytesInt, shuffleWithSeed } from "@xyo-network/chain-utils";
597
616
  import { PayloadBuilder as PayloadBuilder3 } from "@xyo-network/payload-builder";
598
617
  function _ts_decorate6(decorators, target, key, desc) {
@@ -614,13 +633,13 @@ var XyoElectionService = class extends BaseService {
614
633
  super(params);
615
634
  }
616
635
  get chainIterator() {
617
- return assertEx6(this.params.chainIterator, () => "No chain iterator");
636
+ return assertEx7(this.params.chainIterator, () => "No chain iterator");
618
637
  }
619
638
  get chainStakeViewer() {
620
- return assertEx6(this.params.chainStakeViewer, () => "No chain stake viewer");
639
+ return assertEx7(this.params.chainStakeViewer, () => "No chain stake viewer");
621
640
  }
622
641
  get stakeIntentService() {
623
- return assertEx6(this.params.stakeIntentService, () => "No staked intent service");
642
+ return assertEx7(this.params.stakeIntentService, () => "No staked intent service");
624
643
  }
625
644
  async getCreatorCommitteeForNextBlock(current) {
626
645
  return await this.spanAsync("getCreatorCommitteeForNextBlock", async () => {
@@ -648,8 +667,8 @@ XyoElectionService = _ts_decorate6([
648
667
  // src/PendingTransactions/PendingTransactions.ts
649
668
  import { ValueType } from "@opentelemetry/api";
650
669
  import { filterAs, filterAsync } from "@xylabs/array";
651
- import { assertEx as assertEx7 } from "@xylabs/assert";
652
- import { exists } from "@xylabs/exists";
670
+ import { assertEx as assertEx8 } from "@xylabs/assert";
671
+ import { exists as exists2 } from "@xylabs/exists";
653
672
  import { forget } from "@xylabs/forget";
654
673
  import { MemoryArchivist } from "@xyo-network/archivist-memory";
655
674
  import { validateTransaction } from "@xyo-network/chain-validation";
@@ -705,23 +724,23 @@ var XyoPendingTransactionsService = class _XyoPendingTransactionsService extends
705
724
  */
706
725
  _updateCuratedPendingTransactionsArchivistMutex = new Mutex2();
707
726
  get chainArchivist() {
708
- return assertEx7(this.params.chainArchivist, () => "No completed blocks with data archivist");
727
+ return assertEx8(this.params.chainArchivist, () => "No completed blocks with data archivist");
709
728
  }
710
729
  get chainIdentification() {
711
- return assertEx7(this.params.chainIdentification, () => "No chain id");
730
+ return assertEx8(this.params.chainIdentification, () => "No chain id");
712
731
  }
713
732
  get pendingTransactionsArchivist() {
714
- return assertEx7(this.params.pendingTransactionsArchivist, () => "No pending transactions archivist");
733
+ return assertEx8(this.params.pendingTransactionsArchivist, () => "No pending transactions archivist");
715
734
  }
716
735
  get pendingTransactionsCount() {
717
736
  forget(this.countPendingTransactions());
718
737
  return this._pendingTransactionsCount;
719
738
  }
720
739
  get pendingTransactionsLocalArchivist() {
721
- return assertEx7(this._curatedPendingTransactionsArchivist, () => "No pending transactions curated archivist");
740
+ return assertEx8(this._curatedPendingTransactionsArchivist, () => "No pending transactions curated archivist");
722
741
  }
723
742
  get rejectedTransactionsArchivist() {
724
- return assertEx7(this.params.rejectedTransactionsArchivist, () => "No rejected transactions archivist");
743
+ return assertEx8(this.params.rejectedTransactionsArchivist, () => "No rejected transactions archivist");
725
744
  }
726
745
  async createHandler() {
727
746
  await super.createHandler();
@@ -758,11 +777,11 @@ var XyoPendingTransactionsService = class _XyoPendingTransactionsService extends
758
777
  });
759
778
  if (payloads.length === 0) break;
760
779
  cursor = payloads.at(-1)?._sequence;
761
- const transactions = payloads.map((payload) => asOptionalTransactionBoundWitnessWithStorageMeta(payload)).filter(exists);
780
+ const transactions = payloads.map((payload) => asOptionalTransactionBoundWitnessWithStorageMeta(payload)).filter(exists2);
762
781
  foundPendingTransactions.push(...transactions);
763
782
  }
764
783
  const hydratedTransactions = await Promise.all(foundPendingTransactions.map((tx) => tryHydrateTransaction(this.pendingTransactionsLocalArchivist, tx._hash)));
765
- return hydratedTransactions.filter(exists);
784
+ return hydratedTransactions.filter(exists2);
766
785
  }, _XyoPendingTransactionsService.MutexPriority.ReadTransactions);
767
786
  });
768
787
  }
@@ -788,7 +807,7 @@ var XyoPendingTransactionsService = class _XyoPendingTransactionsService extends
788
807
  const unprocessedTransactions = await this.filterAlreadyFinalizedTransactions(payloads);
789
808
  const hydratedUnprocessedTransactions = (await Promise.all(unprocessedTransactions.map((tx) => {
790
809
  return tryHydrateTransaction(this.pendingTransactionsArchivist, tx._hash);
791
- }))).filter(exists);
810
+ }))).filter(exists2);
792
811
  const validTransactions = await filterAsync(hydratedUnprocessedTransactions, async (tx) => {
793
812
  const errors = await validateTransaction(tx, this.chainIdentification.id);
794
813
  return errors.length > 0 ? false : true;
@@ -818,7 +837,7 @@ XyoPendingTransactionsService = _ts_decorate7([
818
837
 
819
838
  // src/StakeIntent/lib/getBlockSignedStakeDeclarations.ts
820
839
  import { filterAs as filterAs2 } from "@xylabs/array";
821
- import { exists as exists2 } from "@xylabs/exists";
840
+ import { exists as exists3 } from "@xylabs/exists";
822
841
  import { asOptionalBoundWitness } from "@xyo-network/boundwitness-model";
823
842
  import { payloadSchemasContains } from "@xyo-network/boundwitness-validator";
824
843
  import { BoundWitnessWrapper } from "@xyo-network/boundwitness-wrapper";
@@ -829,7 +848,7 @@ var getBlockSignedStakeDeclarations = /* @__PURE__ */ __name(async (block, archi
829
848
  const bwsFromBlockWithDeclarations = bwsFromBlock.filter((bw) => payloadSchemasContains(bw, ChainStakeIntentSchema2));
830
849
  const validBlockBwsWithDeclarations = await filterToValidSignedBoundWitnesses(bwsFromBlockWithDeclarations);
831
850
  return (await Promise.all(validBlockBwsWithDeclarations.map(async (bw) => {
832
- const stakeIntentHashes = validBlockBwsWithDeclarations.flatMap(mapBoundWitnessToStakeIntentHashes).filter(exists2);
851
+ const stakeIntentHashes = validBlockBwsWithDeclarations.flatMap(mapBoundWitnessToStakeIntentHashes).filter(exists3);
833
852
  const payloads = await archivist.get(stakeIntentHashes);
834
853
  const stakeIntents = filterAs2(payloads, asOptionalChainStakeIntent).filter((p) => p.intent === intent).filter((p) => bw.addresses.includes(p.from));
835
854
  return stakeIntents;
@@ -845,7 +864,7 @@ var mapBoundWitnessToStakeIntentHashes = /* @__PURE__ */ __name((bw) => {
845
864
 
846
865
  // src/StakeIntent/XyoStakeIntentService.ts
847
866
  import { filterAs as filterAs3 } from "@xylabs/array";
848
- import { assertEx as assertEx8 } from "@xylabs/assert";
867
+ import { assertEx as assertEx9 } from "@xylabs/assert";
849
868
  import { asAddress } from "@xylabs/hex";
850
869
  import { analyzeChain as analyzeChain2, ChainStakeIntentAnalyzer, isChainSummaryStakeIntent } from "@xyo-network/chain-analyze";
851
870
  import { DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS, findFirstMatching, IntervalMap } from "@xyo-network/chain-utils";
@@ -892,16 +911,16 @@ var XyoStakeIntentService = class extends BaseService {
892
911
  });
893
912
  }
894
913
  get chainArchivist() {
895
- return assertEx8(this.params.chainArchivist, () => "chainArchivist not set");
914
+ return assertEx9(this.params.chainArchivist, () => "chainArchivist not set");
896
915
  }
897
916
  get chainIterator() {
898
- return assertEx8(this.params.chainIterator, () => "chainIterator not set");
917
+ return assertEx9(this.params.chainIterator, () => "chainIterator not set");
899
918
  }
900
919
  get chainStakeViewer() {
901
- return assertEx8(this.params.chainStakeViewer, () => "chainStakeViewer not set");
920
+ return assertEx9(this.params.chainStakeViewer, () => "chainStakeViewer not set");
902
921
  }
903
922
  get stakeIntentStateArchivist() {
904
- return assertEx8(this.params.stakeIntentStateArchivist, () => "stakeIntentStateArchivist not set");
923
+ return assertEx9(this.params.stakeIntentStateArchivist, () => "stakeIntentStateArchivist not set");
905
924
  }
906
925
  async createHandler() {
907
926
  const head = await this.chainIterator.head();
@@ -912,13 +931,13 @@ var XyoStakeIntentService = class extends BaseService {
912
931
  }
913
932
  async getDeclaredCandidateRanges(address, intent) {
914
933
  await Promise.resolve();
915
- assertEx8(intent === "producer", () => `Error: Support not yet added for intent ${intent}`);
934
+ assertEx9(intent === "producer", () => `Error: Support not yet added for intent ${intent}`);
916
935
  const results = this._producers.get(address);
917
936
  return results ?? [];
918
937
  }
919
938
  async getDeclaredCandidatesForBlock(block, intent) {
920
939
  return await this.spanAsync("getDeclaredCandidatesForBlock", async () => {
921
- assertEx8(intent === "producer", () => `Error: Support not yet added for intent ${intent}`);
940
+ assertEx9(intent === "producer", () => `Error: Support not yet added for intent ${intent}`);
922
941
  const results = this._producers.findAllContaining(block);
923
942
  const candidates = [
924
943
  ...results
@@ -971,7 +990,7 @@ var XyoStakeIntentService = class extends BaseService {
971
990
  ]);
972
991
  }
973
992
  async recoverState(current) {
974
- const currentBlock = assertEx8(asOptionalBlockBoundWitness((await this.chainArchivist.get([
993
+ const currentBlock = assertEx9(asOptionalBlockBoundWitness((await this.chainArchivist.get([
975
994
  current
976
995
  ]))?.[0]), () => `Block ${current} not found`);
977
996
  const currentBlockNum = currentBlock.block;
@@ -1133,7 +1152,7 @@ var EvmChainService = class extends Base {
1133
1152
  };
1134
1153
 
1135
1154
  // src/XyoChainBlockNumberIterator.ts
1136
- import { assertEx as assertEx9 } from "@xylabs/assert";
1155
+ import { assertEx as assertEx10 } from "@xylabs/assert";
1137
1156
  import { BaseEmitter as BaseEmitter2 } from "@xylabs/events";
1138
1157
  import { isDefined, isNull } from "@xylabs/typeof";
1139
1158
  import { PayloadBuilder as PayloadBuilder5 } from "@xyo-network/payload-builder";
@@ -1169,7 +1188,7 @@ var XyoChainBlockNumberIterator = class _XyoChainBlockNumberIterator extends Bas
1169
1188
  return new _XyoChainBlockNumberIterator(params);
1170
1189
  }
1171
1190
  async get(block) {
1172
- assertEx9(this._head.block >= block, () => `Block requested is newer than the current head [${block}]`);
1191
+ assertEx10(this._head.block >= block, () => `Block requested is newer than the current head [${block}]`);
1173
1192
  const cached = this._blocksByBlockNumber.get(block);
1174
1193
  if (cached) return cached;
1175
1194
  const startingBlock = this._head;
@@ -1178,7 +1197,7 @@ var XyoChainBlockNumberIterator = class _XyoChainBlockNumberIterator extends Bas
1178
1197
  currentBlockHash
1179
1198
  ])).at(0);
1180
1199
  while (isDefined(currentBlock)) {
1181
- assertEx9(asBlockBoundWitness2(currentBlock), () => `Expected hash to be a block bound witness [${currentBlock?._hash}]`);
1200
+ assertEx10(asBlockBoundWitness2(currentBlock), () => `Expected hash to be a block bound witness [${currentBlock?._hash}]`);
1182
1201
  if (isBlockBoundWitness(currentBlock)) {
1183
1202
  this._blocksByBlockNumber.set(currentBlock.block, currentBlock);
1184
1203
  if (currentBlock.block === block) {
@@ -1217,7 +1236,7 @@ var XyoChainBlockNumberIterator = class _XyoChainBlockNumberIterator extends Bas
1217
1236
  currentBlock = asOptionalBlockBoundWitness2(nextBlock[0]);
1218
1237
  } else {
1219
1238
  const hash = PayloadBuilder5.hash(currentBlock);
1220
- assertEx9(asBlockBoundWitness2(currentBlock), () => `Expected hash to be a block bound witness [${hash}]`);
1239
+ assertEx10(asBlockBoundWitness2(currentBlock), () => `Expected hash to be a block bound witness [${hash}]`);
1221
1240
  }
1222
1241
  }
1223
1242
  return results;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/AccountBalance/XyoChainAccountBalanceService.ts","../../src/BaseService.ts","../../src/BaseEthProvider.ts","../../src/BlockProducer/XyoBlockProducer.ts","../../src/BlockProducer/generateTransactionTransfers.ts","../../src/BlockReward/EvmBlockRewardService.ts","../../src/BlockReward/XyoBlockRewardService.ts","../../src/ChainValidator/XyoValidator.ts","../../src/Election/XyoElectionService.ts","../../src/PendingTransactions/PendingTransactions.ts","../../src/StakeIntent/lib/getBlockSignedStakeDeclarations.ts","../../src/StakeIntent/XyoStakeIntentService.ts","../../src/Staker/Evm/Evm.ts","../../src/XyoChainBlockNumberIterator.ts"],"sourcesContent":["import { assertEx } from '@xylabs/assert'\nimport {\n Address, Hash, Hex,\n toHex,\n} from '@xylabs/hex'\nimport {\n analyzeChain, BalanceAnalyzer, isChainSummaryBalances,\n} from '@xyo-network/chain-analyze'\nimport { SignedBigInt, toPositiveBigInt } from '@xyo-network/chain-protocol'\nimport {\n AccountBalanceService, BaseServiceParams,\n ChainServiceCollection,\n} from '@xyo-network/xl1-protocol'\n\nimport { BaseService, creatableService } from '../BaseService.ts'\n\nexport type ChainAccountBalanceServiceParams = BaseServiceParams<Partial<Pick<ChainServiceCollection, 'chainArchivist'>>>\n\n@creatableService()\nexport class XyoChainAccountBalanceService extends BaseService<ChainAccountBalanceServiceParams> implements AccountBalanceService {\n private _balances: Record<Address, SignedBigInt> = {}\n private _previousHead: Hash | null = null\n\n protected get chainArchivist() {\n return assertEx(this.params.chainArchivist, () => 'chainArchivist is required')\n }\n\n getBalance(address: Address): Hex {\n return toPositiveBigInt(this._balances[address] ?? { positive: toHex(0n) }).positive\n }\n\n getBalances(): Record<Address, Hex> {\n const result: Record<Address, Hex> = {}\n const entries = Object.entries(this._balances) as [Address, SignedBigInt][]\n for (const [address, balance] of entries) {\n result[address] = toPositiveBigInt(balance).positive\n }\n return result\n }\n\n async sync(head: Hash): Promise<void> {\n const analysis = await analyzeChain(\n this.chainArchivist,\n [new BalanceAnalyzer()],\n head,\n this._previousHead,\n -1n,\n this.tracer,\n )\n this._balances = assertEx(analysis.find(isChainSummaryBalances)?.balances, () => 'Failed to sync balances')\n }\n}\n","import { BaseEmitter } from '@xylabs/events'\nimport type { Promisable } from '@xylabs/promise'\nimport { span, spanAsync } from '@xyo-network/chain-utils'\nimport type {\n BaseAccountableServiceParams, BaseServiceParams, Service,\n} from '@xyo-network/xl1-protocol'\nimport { Mutex } from 'async-mutex'\n\ndeclare global {\n var xyoServiceSingletons: Record<string, unknown>\n}\n\nexport class BaseService<TParams extends BaseServiceParams = BaseServiceParams> extends BaseEmitter<TParams> {\n private static singletonInitMutex = new Mutex()\n\n static get singletons() {\n return globalThis['xyoServiceSingletons'] ?? (globalThis['xyoServiceSingletons'] = {})\n }\n\n get name() {\n return this.constructor.name\n }\n\n static async create<TService extends BaseService<TParams>, TParams extends BaseServiceParams = TService['params']>(\n this: CreatableService<TService>,\n params: TParams,\n ): Promise<TService> {\n const result = new this(params)\n if (result.name === 'BaseService') throw new Error('Cannot create BaseService')\n await result.createHandler()\n return result\n }\n\n static initSingleton<TService extends BaseService<TParams>, TParams extends BaseServiceParams>(params: TParams) {\n if (this.singletons[this.name]) throw new Error(`Singleton already initialized for ${this.name}`)\n return this.singletonInitMutex.runExclusive(async () => {\n return await this.create(params) as TService\n })\n }\n\n createHandler(): Promisable<void> {\n return\n }\n\n span<T>(name: string, fn: () => T): T {\n return span(name, fn, this.tracer)\n }\n\n async spanAsync<T>(name: string, fn: () => Promise<T>): Promise<T> {\n return await spanAsync(name, fn, this.tracer)\n }\n}\n\nexport abstract class BaseAccountableService<\n TParams extends BaseAccountableServiceParams = BaseAccountableServiceParams,\n> extends BaseService<TParams> {\n // Base class for services that have an account\n}\n\nexport interface CreatableService<T extends BaseService = BaseService> extends Service {\n new(params: T['params']): T\n create<T extends BaseService>(this: CreatableService<T>, params: T['params']): Promisable<T>\n}\n\nexport function creatableService<T extends BaseService = BaseService>() {\n return <U extends CreatableService<T>>(constructor: U) => {\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n constructor\n }\n}\n","import type {\n Address, BlockAPI,\n BlockNumberOrTag,\n CompileResultAPI,\n EthExecutionAPI,\n FeeHistoryResultAPI,\n Filter,\n FilterResultsAPI,\n HexString, HexString8Bytes,\n HexString32Bytes,\n HexString256Bytes,\n HexStringBytes,\n SignedTransactionInfoAPI,\n SyncingStatusAPI,\n TransactionCallAPI,\n TransactionInfoAPI,\n TransactionReceiptAPI,\n TransactionWithSenderAPI,\n Uint,\n Uint256,\n} from 'web3-types'\n\nexport class BaseEthProvider implements EthExecutionAPI {\n eth_accounts(): Address[] {\n throw new Error('Method not implemented.')\n }\n\n eth_blockNumber(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_call(_transaction: TransactionCallAPI, _blockNumber: BlockNumberOrTag): HexStringBytes {\n throw new Error('Method not implemented.')\n }\n\n eth_clearSubscriptions(_keepSyncing?: boolean): void {\n throw new Error('Method not implemented.')\n }\n\n eth_coinbase(): Address {\n throw new Error('Method not implemented.')\n }\n\n eth_compileLLL(_code: string): HexStringBytes {\n throw new Error('Method not implemented.')\n }\n\n eth_compileSerpent(_code: string): HexStringBytes {\n throw new Error('Method not implemented.')\n }\n\n eth_compileSolidity(_code: string): CompileResultAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_estimateGas(_transaction: Partial<TransactionWithSenderAPI>, _blockNumber: BlockNumberOrTag): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_feeHistory(_blockCount: Uint, _newestBlock: BlockNumberOrTag, _rewardPercentiles: number[]): FeeHistoryResultAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_gasPrice(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getBalance(_address: Address, _blockNumber: BlockNumberOrTag): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getBlockByHash(_blockHash: HexString32Bytes, _hydrated: boolean): BlockAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getBlockByNumber(_blockNumber: BlockNumberOrTag, _hydrated: boolean): BlockAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getBlockTransactionCountByHash(_blockHash: HexString32Bytes): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getBlockTransactionCountByNumber(_blockNumber: BlockNumberOrTag): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getCode(_address: Address, _blockNumber: BlockNumberOrTag): HexStringBytes {\n throw new Error('Method not implemented.')\n }\n\n eth_getCompilers(): string[] {\n throw new Error('Method not implemented.')\n }\n\n eth_getFilterChanges(_filterIdentifier: Uint): FilterResultsAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getFilterLogs(_filterIdentifier: Uint): FilterResultsAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getLogs(_filter: Filter): FilterResultsAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getStorageAt(_address: Address, _storageSlot: Uint256, _blockNumber: BlockNumberOrTag): HexStringBytes {\n throw new Error('Method not implemented.')\n }\n\n eth_getTransactionByBlockHashAndIndex(_blockHash: HexString32Bytes, _transactionIndex: Uint): TransactionInfoAPI | undefined {\n throw new Error('Method not implemented.')\n }\n\n eth_getTransactionByBlockNumberAndIndex(_blockNumber: BlockNumberOrTag, _transactionIndex: Uint): TransactionInfoAPI | undefined {\n throw new Error('Method not implemented.')\n }\n\n eth_getTransactionByHash(_transactionHash: HexString32Bytes): TransactionInfoAPI | undefined {\n throw new Error('Method not implemented.')\n }\n\n eth_getTransactionCount(_address: Address, _blockNumber: BlockNumberOrTag): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getTransactionReceipt(_transactionHash: HexString32Bytes): TransactionReceiptAPI | undefined {\n throw new Error('Method not implemented.')\n }\n\n eth_getUncleByBlockHashAndIndex(_blockHash: HexString32Bytes, _uncleIndex: Uint): BlockAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getUncleByBlockNumberAndIndex(_blockNumber: BlockNumberOrTag, _uncleIndex: Uint): BlockAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getUncleCountByBlockHash(_blockHash: HexString32Bytes): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getUncleCountByBlockNumber(_blockNumber: BlockNumberOrTag): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getWork(): [HexString32Bytes, HexString32Bytes, HexString32Bytes] {\n throw new Error('Method not implemented.')\n }\n\n eth_hashrate(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_maxPriorityFeePerGas(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_mining(): boolean {\n throw new Error('Method not implemented.')\n }\n\n eth_newBlockFilter(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_newFilter(_filter: Filter): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_newPendingTransactionFilter(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_protocolVersion(): string {\n throw new Error('Method not implemented.')\n }\n\n eth_sendRawTransaction(_transaction: HexStringBytes): HexString32Bytes {\n throw new Error('Method not implemented.')\n }\n\n eth_sendTransaction(_transaction: TransactionWithSenderAPI | Partial<TransactionWithSenderAPI>): HexString32Bytes {\n throw new Error('Method not implemented.')\n }\n\n eth_sign(_address: Address, _message: HexStringBytes): HexString256Bytes {\n throw new Error('Method not implemented.')\n }\n\n eth_signTransaction(_transaction: TransactionWithSenderAPI | Partial<TransactionWithSenderAPI>): HexStringBytes | SignedTransactionInfoAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_submitHashrate(_hashRate: HexString32Bytes, _id: HexString32Bytes): boolean {\n throw new Error('Method not implemented.')\n }\n\n eth_submitWork(_nonce: HexString8Bytes, _hash: HexString32Bytes, _digest: HexString32Bytes): boolean {\n throw new Error('Method not implemented.')\n }\n\n eth_subscribe(..._params: ['newHeads'] | ['newPendingTransactions'] | ['syncing'] | ['logs', { address?: HexString; topics?: HexString[] }]): HexString {\n throw new Error('Method not implemented.')\n }\n\n eth_syncing(): SyncingStatusAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_uninstallFilter(_filterIdentifier: Uint): boolean {\n throw new Error('Method not implemented.')\n }\n\n eth_unsubscribe(_subscriptionId: HexString): HexString {\n throw new Error('Method not implemented.')\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Address, toHex } from '@xylabs/hex'\nimport { isUndefined } from '@xylabs/typeof'\nimport { ArchivistInstance, ReadArchivist } from '@xyo-network/archivist-model'\nimport {\n BlockRewardDiviner, FixedPercentageBlockRewardDiviner, FixedPercentageBlockRewardDivinerConfigSchema,\n} from '@xyo-network/chain-modules'\nimport { buildBlock } from '@xyo-network/chain-protocol'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport { WithStorageMeta } from '@xyo-network/payload-model'\nimport {\n AllowedBlockPayload, asBlockBoundWitness, BlockBoundWitness, BlockNumber, BlockNumberSchema, BlockProducer, ChainStakeIntent, ChainStakeIntentSchema,\n HydratedBlock, PendingTransactionsService, StakeIntentService, Transfer,\n} from '@xyo-network/xl1-protocol'\n\nimport { BaseService, creatableService } from '../BaseService.ts'\nimport { XyoValidatorParams } from '../ChainValidator/index.ts'\nimport { generateTransactionTransfers } from './generateTransactionTransfers.ts'\n\n/**\n * The default block size for a block\n */\nexport const DEFAULT_BLOCK_SIZE = 10\n\n// /**\n// * The amount of time for which a producer will restake their intent\n// */\nexport const XYO_PRODUCER_RESTAKE_DURATION = 10_000\n\n/**\n * The number of blocks within which a producer will redeclare\n * their intent to produce blocks\n */\nexport const XYO_PRODUCER_RESTAKE_WINDOW = 500n\n\nexport interface XyoBlockProducerParams extends XyoValidatorParams {\n pendingTransactionsArchivist?: ReadArchivist\n pendingTransactionsService?: PendingTransactionsService\n rejectedTransactionsArchivist?: ArchivistInstance\n rewardAddress?: Address\n stakeIntentService?: StakeIntentService\n}\n\n@creatableService()\nexport class XyoBlockProducer extends BaseService<XyoBlockProducerParams> implements BlockProducer {\n protected _blockRewardDiviner: BlockRewardDiviner | undefined\n\n static get DefaultBlockSize(): number {\n return DEFAULT_BLOCK_SIZE\n }\n\n get address() {\n return this.account.address\n }\n\n protected get account() {\n return assertEx(this.params.account, () => 'account is required')\n }\n\n protected get chainFinalizedArchivist() {\n return assertEx(this.params.chainFinalizedArchivist, () => 'chainFinalizedArchivist is required')\n }\n\n protected get chainInfo() {\n return assertEx(this.params.chainInformation, () => 'chainInfo is required')\n }\n\n protected get electionService() {\n return assertEx(this.params.electionService, () => 'electionService is required')\n }\n\n protected get pendingTransactions() {\n return assertEx(this.params.pendingTransactions, () => 'pendingTransactions is required')\n }\n\n protected get pendingTransactionsService() {\n return assertEx(this.params.pendingTransactionsService, () => 'Missing pendingTransactionsService')\n }\n\n protected get rejectedTransactionsArchivist() {\n return assertEx(this.params.rejectedTransactionsArchivist, () => 'No rejected transactions archivist')\n }\n\n protected get rewardAddress(): Address {\n return assertEx(this.params.rewardAddress, () => 'No reward address provided')\n }\n\n protected get rewardService() {\n return assertEx(this.params.rewardService, () => 'rewardService is required')\n }\n\n protected get stakeIntentService(): StakeIntentService {\n return assertEx(this.params.stakeIntentService, () => 'No StakeIntentService provided')\n }\n\n protected get validateHydratedBlockState() {\n return assertEx(this.params.validateHydratedBlockState, () => 'validateHydratedBlockState is required')\n }\n\n async next(head: WithStorageMeta<BlockBoundWitness>): Promise<HydratedBlock | undefined> {\n // If the block is for another chain, ignore\n if (head.chain !== this.chainInfo.id) return\n const leaders = await this.electionService.getCreatorCommitteeForNextBlock(head)\n // TODO: Should we propose block if creator committee is empty?\n // TODO: Handle the case where we're not the 1st leader but they're not responding\n // at a higher level than here as that's a network issue\n if (leaders?.[0] !== this.address) return\n return this.proposeNextValidBlock(head)\n }\n\n protected async getBlockRewardTransfer(block: number): Promise<Transfer | undefined> {\n if (!this._blockRewardDiviner) {\n // TODO: Adjust to allow for genesis block reward vs. normal block reward\n this._blockRewardDiviner = await FixedPercentageBlockRewardDiviner.create({\n account: 'random',\n blockRewardService: this.rewardService,\n config: {\n rewardAddress: this.rewardAddress,\n rewardPercentageRatio: 0,\n schema: FixedPercentageBlockRewardDivinerConfigSchema,\n },\n })\n }\n const blockHex = assertEx(toHex(block), () => 'Failed to convert block to hex')\n const blockId = new PayloadBuilder<BlockNumber>({ schema: BlockNumberSchema }).fields({ block: blockHex }).build()\n const rewards = await this._blockRewardDiviner.divine([blockId])\n const [reward] = rewards\n return reward\n }\n\n /**\n * Handles the producer redeclaration logic\n * @param head The current head block\n * @returns\n */\n protected async getProducerRedeclaration(head: WithStorageMeta<BlockBoundWitness>): Promise<ChainStakeIntent | undefined> {\n const redeclareIntent = process.env.XYO_PRODUCER_REDECLARE_INTENT\n if (isUndefined(redeclareIntent)) return\n // Decide if we need to redeclare\n const ranges = await this.stakeIntentService.getDeclaredCandidateRanges(this.address, 'producer')\n // TODO: This doesn't handle the case where the producer had declared a range for the future\n // but we're in a range that's not the future\n // Sort in ascending order based on ending range to get range with highest ending block\n const lastRange = ranges.toSorted((a, b) => a[1] > b[1] ? 1 : -1).at(-1)\n if (!lastRange) return\n const [, currentDeclarationEnd] = lastRange\n const currentBlock = head.block\n const timeToProducerExpiration = currentDeclarationEnd - currentBlock\n if (timeToProducerExpiration > XYO_PRODUCER_RESTAKE_WINDOW) return\n // Create redeclaration\n const intent = new PayloadBuilder<ChainStakeIntent>({ schema: ChainStakeIntentSchema }).fields({\n from: this.address,\n intent: 'producer',\n nbf: currentBlock,\n exp: currentBlock + XYO_PRODUCER_RESTAKE_DURATION,\n }).build()\n return intent\n }\n\n protected async proposeNextValidBlock(head: WithStorageMeta<BlockBoundWitness>): Promise<HydratedBlock | undefined> {\n return await this.spanAsync('proposeNextValidBlock', async () => {\n // Calculate the next block components\n const { block: previousBlock } = assertEx(asBlockBoundWitness(head), () => 'Invalid head block')\n const nextBlock = previousBlock + 1\n const nextBlockTransactions = await this.pendingTransactionsService.getPendingTransactions(head._hash, XyoBlockProducer.DefaultBlockSize)\n\n const blockPayloads: AllowedBlockPayload[] = []\n\n // Calculate the optional producer redeclaration and add it if necessary\n const producerRedeclarationPayload = await this.getProducerRedeclaration(head)\n if (producerRedeclarationPayload) blockPayloads.push(producerRedeclarationPayload)\n\n // If there are no transactions and no payloads, we don't need to create a block\n if (blockPayloads.length === 0 && nextBlockTransactions.length === 0) return\n\n // Calculate the optional block reward transfer and add if necessary\n const rewardTransferPayload = await this.getBlockRewardTransfer(nextBlock)\n if (rewardTransferPayload) blockPayloads.push(rewardTransferPayload)\n\n const transactionTransfers = await generateTransactionTransfers(this.address, nextBlockTransactions)\n blockPayloads.push(...transactionTransfers)\n\n // Build the block\n const block = await buildBlock(head, nextBlockTransactions, blockPayloads, [this.account])\n console.log('buildBlock', block)\n const errors = await this.validateHydratedBlockState(block, this.chainInfo.id, this.chainFinalizedArchivist)\n if (errors.length > 0) {\n this.logger?.error('Validation of produced block failed', errors)\n const rejectedTransactions = block[1]\n await this.rejectedTransactionsArchivist.insert(rejectedTransactions)\n } else {\n return block\n }\n })\n }\n}\n","import { type Address, hexFromBigInt } from '@xylabs/hex'\nimport { HydratedTransactionWrapper } from '@xyo-network/chain-wrappers'\nimport {\n type HydratedTransaction, type Transfer, TransferSchema,\n} from '@xyo-network/xl1-protocol'\n\nexport async function generateTransactionTransfers(address: Address, transactions: HydratedTransaction[]): Promise<Transfer[]> {\n const txs = await Promise.all(transactions.map(tx => HydratedTransactionWrapper.parse(tx)))\n\n // merge transactions with the same from address\n const txCosts: [Address, bigint][] = []\n for (const tx of txs) {\n const existingItem = txCosts.find(([addr]) => addr === tx.boundWitness.from)\n if (existingItem) {\n existingItem[1] += tx.fees.base\n } else {\n txCosts.push([tx.boundWitness.from, tx.fees.base])\n }\n }\n\n // generate actual Transfer Payloads\n const payloads = txCosts.map(([from, amount]) => {\n const payload: Transfer = {\n schema: TransferSchema,\n epoch: Date.now(),\n from,\n // TODO: add function to Wrapper to calculate entire cost of transaction\n transfers: { [address]: hexFromBigInt(amount) },\n }\n return payload\n })\n return payloads\n}\n","import { assertEx } from '@xylabs/assert'\nimport { XyoChainRewards__factory as XyoChainRewardsFactory } from '@xyo-network/typechain'\nimport {\n BaseAccountableServiceParams, BlockRewardService, ChainService,\n toEthAddress,\n} from '@xyo-network/xl1-protocol'\nimport { Provider } from 'ethers/providers'\n\nimport { BaseService, creatableService } from '../BaseService.ts'\n\nexport interface EvmBlockRewardServiceParams extends BaseAccountableServiceParams {\n chainService?: ChainService\n provider?: Provider\n}\n\n@creatableService<EvmBlockRewardService>()\nexport class EvmBlockRewardService extends BaseService<EvmBlockRewardServiceParams> implements BlockRewardService {\n protected _contractAddress: string | undefined\n\n protected get chainService() {\n return assertEx(this.params.chainService, () => 'chainService is required')\n }\n\n protected get contractAddress() {\n return assertEx(this._contractAddress, () => 'contractAddress is required')\n }\n\n protected get provider() {\n return assertEx(this.params.provider, () => 'provider is required')\n }\n\n override async createHandler() {\n await super.createHandler()\n this._contractAddress = await this.chainService.rewardsContract()\n }\n\n async getRewardForBlock(blockNumber: bigint): Promise<bigint> {\n const contract = XyoChainRewardsFactory.connect(toEthAddress(this.contractAddress), this.provider)\n return await contract.calcBlockReward(blockNumber)\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { toFixedPoint } from '@xylabs/decimal-precision'\nimport { Promisable } from '@xylabs/promise'\nimport { rewardFromBlockNumber } from '@xyo-network/chain-protocol'\nimport { BaseServiceParams, BlockRewardService } from '@xyo-network/xl1-protocol'\n\nimport { BaseService, creatableService } from '../BaseService.ts'\n\nexport interface XyoBlockRewardServiceParams extends BaseServiceParams {\n creatorReward?: bigint\n initialStepReward?: bigint\n minRewardPerBlock?: bigint\n stepFactorDenominator?: bigint\n stepFactorNumerator?: bigint\n stepSize?: bigint\n}\n\n@creatableService()\nexport class XyoBlockRewardService extends BaseService<XyoBlockRewardServiceParams> implements BlockRewardService {\n protected readonly rewardFromBlockNumber = rewardFromBlockNumber(18)\n\n constructor(\n {\n creatorReward = toFixedPoint(20_000_000_000n),\n initialStepReward = toFixedPoint(3000n),\n minRewardPerBlock = toFixedPoint(30n),\n stepFactorDenominator = 100n,\n stepFactorNumerator = 90n,\n stepSize = 1_000_000n,\n }: Partial<XyoBlockRewardServiceParams> = {},\n ) {\n super({\n initialStepReward, minRewardPerBlock, stepSize, stepFactorDenominator, stepFactorNumerator, creatorReward,\n })\n }\n\n get creatorReward() {\n return assertEx(this.params.creatorReward, () => 'creatorReward is required')\n }\n\n get initialReward() {\n return assertEx(this.params.initialStepReward, () => 'initialStepReward is required')\n }\n\n get minRewardPerBlock() {\n return assertEx(this.params.minRewardPerBlock, () => 'minRewardPerBlock is required')\n }\n\n get stepFactorDenominator() {\n return assertEx(this.params.stepFactorDenominator, () => 'stepFactorDenominator is required')\n }\n\n get stepFactorNumerator() {\n return assertEx(this.params.stepFactorNumerator, () => 'stepFactorNumerator is required')\n }\n\n get stepSize() {\n return assertEx(this.params.stepSize, () => 'stepSize is required')\n }\n\n getRewardForBlock(blockNumber: bigint): Promisable<bigint> {\n return this.rewardFromBlockNumber(\n blockNumber,\n this.initialReward,\n this.stepSize,\n this.stepFactorNumerator,\n this.stepFactorDenominator,\n this.minRewardPerBlock,\n this.creatorReward,\n )\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Promisable } from '@xylabs/promise'\nimport { AccountInstance } from '@xyo-network/account-model'\nimport { ArchivistInstance, ReadArchivist } from '@xyo-network/archivist-model'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport {\n BaseServiceParams,\n BlockBoundWitness,\n BlockRewardService,\n ChainInformation,\n ElectionService,\n HydratedBlockStateValidationFunction,\n HydratedTransaction,\n HydratedTransactionWithStorageMeta,\n StakeIntentService,\n} from '@xyo-network/xl1-protocol'\n\nimport { BaseService, creatableService } from '../BaseService.ts'\nimport { Validator } from './model/index.ts'\n\nconst addStorageMeta = async ([tx, payloads]: HydratedTransaction): Promise<HydratedTransactionWithStorageMeta> => {\n return [await PayloadBuilder.addStorageMeta(tx), await PayloadBuilder.addStorageMeta(payloads)]\n}\n\nexport interface XyoValidatorParams extends BaseServiceParams {\n account?: AccountInstance\n chainFinalizedArchivist?: ReadArchivist\n chainInformation?: ChainInformation\n electionService?: ElectionService\n pendingTransactions?: ArchivistInstance\n rewardService?: BlockRewardService\n stakeIntentService?: StakeIntentService\n validateHydratedBlockState?: HydratedBlockStateValidationFunction\n}\n\n@creatableService()\nexport class XyoValidator<TParams extends XyoValidatorParams = XyoValidatorParams> extends BaseService<TParams> implements Validator {\n get address() {\n return this.account.address\n }\n\n protected get account() {\n return assertEx(this.params.account, () => 'account is required')\n }\n\n protected get chainFinalizedArchivist() {\n return assertEx(this.params.chainFinalizedArchivist, () => 'chainFinalizedArchivist is required')\n }\n\n protected get chainInfo() {\n return assertEx(this.params.chainInformation, () => 'chainInfo is required')\n }\n\n protected get electionService() {\n return assertEx(this.params.electionService, () => 'electionService is required')\n }\n\n protected get pendingTransactions() {\n return assertEx(this.params.pendingTransactions, () => 'pendingTransactions is required')\n }\n\n protected get rewardService() {\n return assertEx(this.params.rewardService, () => 'rewardService is required')\n }\n\n validatePendingBlock(_block: BlockBoundWitness): Promisable<Error[]> {\n return [] // await validateBlockProtocol(block, this.chainInfo)\n }\n\n // TODO: Move to validator and inherit this class from validator\n async validatePendingTransaction(hydratedTransaction: HydratedTransaction): Promise<boolean> {\n const [tx] = await addStorageMeta(hydratedTransaction)\n // Ensure not confirmed already (replay attack)\n if ((await this.chainFinalizedArchivist.get([tx._hash])).length > 0) return false\n // TODO: Ensure transaction is valid (double spend, has voucher, has required stake, etc.)\n // TODO: Ensure validator stake is valid\n return await Promise.resolve(true)\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Address, Hash } from '@xylabs/hex'\nimport { hexToLast4BytesInt, shuffleWithSeed } from '@xyo-network/chain-utils'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport type {\n BaseServiceParams, ChainBlockNumberIterator, ChainStakeViewer, StakeIntentService,\n} from '@xyo-network/xl1-protocol'\nimport { BlockBoundWitness, ElectionService } from '@xyo-network/xl1-protocol'\n\nimport { BaseService, creatableService } from '../BaseService.ts'\n\nexport interface XyoElectionServicesParams extends BaseServiceParams {\n chainIterator?: ChainBlockNumberIterator\n chainStakeViewer?: ChainStakeViewer\n stakeIntentService?: StakeIntentService\n}\n\n@creatableService()\nexport class XyoElectionService extends BaseService<XyoElectionServicesParams> implements ElectionService {\n constructor(params: XyoElectionServicesParams) {\n super(params)\n }\n\n get chainIterator() {\n return assertEx(this.params.chainIterator, () => 'No chain iterator')\n }\n\n get chainStakeViewer() {\n return assertEx(this.params.chainStakeViewer, () => 'No chain stake viewer')\n }\n\n get stakeIntentService() {\n return assertEx(this.params.stakeIntentService, () => 'No staked intent service')\n }\n\n async getCreatorCommitteeForNextBlock(current: BlockBoundWitness): Promise<Address[]> {\n return await this.spanAsync('getCreatorCommitteeForNextBlock', async () => {\n const nextBlock = current.block + 1\n const candidates = await this.stakeIntentService.getDeclaredCandidatesForBlock(nextBlock, 'producer')\n const previousBlockHash = await PayloadBuilder.hash(current)\n return this.generateCreatorCommittee(candidates, previousBlockHash)\n })\n }\n\n protected generateCreatorCommittee(candidates: Address[], previousBlockHash: Hash, maxSize = 3): Address[] {\n const creators = new Set<Address>(candidates)\n const seed = hexToLast4BytesInt(previousBlockHash)\n const creatorArray = shuffleWithSeed(creators, seed)\n return creatorArray.slice(0, maxSize)\n }\n}\n","import { ValueType } from '@opentelemetry/api'\nimport { filterAs, filterAsync } from '@xylabs/array'\nimport { assertEx } from '@xylabs/assert'\nimport { exists } from '@xylabs/exists'\nimport { forget } from '@xylabs/forget'\nimport { Hash } from '@xylabs/hex'\nimport { MemoryArchivist } from '@xyo-network/archivist-memory'\nimport { ArchivistInstance } from '@xyo-network/archivist-model'\nimport { validateTransaction } from '@xyo-network/chain-validation'\nimport {\n Payload, Sequence, WithStorageMeta,\n} from '@xyo-network/payload-model'\nimport {\n asOptionalTransactionBoundWitnessWithStorageMeta, BaseServiceParams, ChainIdentification, HydratedTransactionWithStorageMeta,\n PendingTransactionsService, TransactionBoundWitness,\n} from '@xyo-network/xl1-protocol'\nimport { flattenHydratedTransactions, tryHydrateTransaction } from '@xyo-network/xl1-protocol-sdk'\nimport { Mutex } from 'async-mutex'\n\nimport { BaseService, creatableService } from '../BaseService.ts'\n\nexport interface XyoPendingTransactionsServiceParams extends BaseServiceParams {\n chainArchivist?: ArchivistInstance\n chainIdentification?: ChainIdentification\n pendingTransactionsArchivist?: ArchivistInstance\n rejectedTransactionsArchivist?: ArchivistInstance\n}\n\n@creatableService()\nexport class XyoPendingTransactionsService extends BaseService<XyoPendingTransactionsServiceParams> implements PendingTransactionsService {\n private static readonly MutexPriority = {\n /**\n * Priority for inserting new transactions\n */\n InsertNewTransactions: 5,\n /**\n * Priority for reading pending transactions\n */\n ReadTransactions: 3,\n /**\n * Priority for removing rejected transactions\n */\n RemoveRejectedTransactions: 2,\n /**\n * Priority for removing finalized transactions\n */\n RemoveFinalizedTransactions: 1,\n } as const\n\n /**\n * A mutex to ensure that the counting the number of pending transactions is\n * not called concurrently\n */\n private _countPendingTransactionsMutex = new Mutex()\n\n /**\n * A local Archivist optimized for fast retrieval that stores only validated\n * pending transactions\n */\n private _curatedPendingTransactionsArchivist: MemoryArchivist | undefined\n\n /**\n * The last count of total pending transactions\n */\n private _pendingTransactionsCount: number = 0\n\n /**\n * A mutex to ensure that the curated pending transactions archivist is\n * updated in a thread-safe manner\n */\n private _updateCuratedPendingTransactionsArchivistMutex = new Mutex()\n\n private get chainArchivist() {\n return assertEx(this.params.chainArchivist, () => 'No completed blocks with data archivist')\n }\n\n private get chainIdentification() {\n return assertEx(this.params.chainIdentification, () => 'No chain id')\n }\n\n private get pendingTransactionsArchivist() {\n return assertEx(this.params.pendingTransactionsArchivist, () => 'No pending transactions archivist')\n }\n\n private get pendingTransactionsCount() {\n forget(this.countPendingTransactions())\n return this._pendingTransactionsCount\n }\n\n private get pendingTransactionsLocalArchivist() {\n return assertEx(this._curatedPendingTransactionsArchivist, () => 'No pending transactions curated archivist')\n }\n\n private get rejectedTransactionsArchivist() {\n return assertEx(this.params.rejectedTransactionsArchivist, () => 'No rejected transactions archivist')\n }\n\n override async createHandler() {\n await super.createHandler()\n this._curatedPendingTransactionsArchivist = await MemoryArchivist.create({ account: 'random' })\n\n // On new pending transactions, insert them into the curated archivist\n this.pendingTransactionsArchivist.on('inserted', async ({ payloads }) => {\n await this.insertNewTransactions(payloads)\n })\n\n // On new finalized blocks, remove the transactions from the curated archivist\n this.chainArchivist.on('inserted', async ({ payloads }) => {\n await this.removeFinalizedTransactions(payloads)\n })\n\n // On new rejected blocks, remove the transactions from the curated archivist\n this.rejectedTransactionsArchivist.on('inserted', async ({ payloads }) => {\n await this.removeRejectedTransactions(payloads)\n })\n\n const pendingTransactionsGauge = this.meter?.createObservableGauge(\n 'xyo_pending_transactions_count',\n { description: 'The current number of pending transactions', valueType: ValueType.INT },\n )\n pendingTransactionsGauge?.addCallback((observer) => {\n observer.observe(this.pendingTransactionsCount)\n })\n }\n\n async getPendingTransactions(head: Hash, limit: number): Promise<HydratedTransactionWithStorageMeta[]> {\n return await this.spanAsync('getPendingTransactions', async () => {\n return await this._updateCuratedPendingTransactionsArchivistMutex.runExclusive(async () => {\n const foundPendingTransactions: WithStorageMeta<TransactionBoundWitness>[] = []\n let cursor: Sequence | undefined\n while (foundPendingTransactions.length < limit) {\n const payloads = await this.pendingTransactionsLocalArchivist.next({\n limit: 100, order: 'asc', cursor,\n })\n if (payloads.length === 0) break\n cursor = payloads.at(-1)?._sequence\n const transactions = payloads.map(payload => asOptionalTransactionBoundWitnessWithStorageMeta(payload)).filter(exists)\n foundPendingTransactions.push(...transactions)\n }\n const hydratedTransactions = await Promise.all(\n foundPendingTransactions.map(tx => tryHydrateTransaction(this.pendingTransactionsLocalArchivist, tx._hash)),\n )\n return hydratedTransactions.filter(exists)\n }, XyoPendingTransactionsService.MutexPriority.ReadTransactions)\n })\n }\n\n private async countPendingTransactions() {\n if (this._countPendingTransactionsMutex.isLocked()) return\n await this._countPendingTransactionsMutex.runExclusive(async () => {\n const payloads = (await this._curatedPendingTransactionsArchivist?.all()) ?? []\n const pendingTransactions = filterAs(payloads, asOptionalTransactionBoundWitnessWithStorageMeta)\n this._pendingTransactionsCount = pendingTransactions.length\n })\n }\n\n private async filterAlreadyFinalizedTransactions(payloads: WithStorageMeta<Payload>[]): Promise<WithStorageMeta<TransactionBoundWitness>[]> {\n const incomingTransactions = filterAs(payloads, asOptionalTransactionBoundWitnessWithStorageMeta)\n const incomingTransactionHashes = incomingTransactions.map(payload => payload._hash)\n const finalizedTransactions = await this.chainArchivist.get(incomingTransactionHashes)\n const finalizedTransactionHashes = new Set(finalizedTransactions.map(item => item._hash))\n const nonFinalizedTransactions = incomingTransactions.filter(item => !finalizedTransactionHashes.has(item._hash))\n return nonFinalizedTransactions\n }\n\n private async insertNewTransactions(payloads: WithStorageMeta<Payload>[]) {\n return await this.spanAsync('InsertNewTransactions', async () => {\n return await this._updateCuratedPendingTransactionsArchivistMutex.runExclusive(async () => {\n // Check incoming transactions against finalized transactions\n const unprocessedTransactions = await this.filterAlreadyFinalizedTransactions(payloads)\n // Hydrate all unprocessed transactions\n const hydratedUnprocessedTransactions = (await Promise.all(unprocessedTransactions.map((tx) => {\n return tryHydrateTransaction(this.pendingTransactionsArchivist, tx._hash)\n }))).filter(exists)\n // Filter to only valid transactions\n const validTransactions = await filterAsync(hydratedUnprocessedTransactions, async (tx) => {\n const errors = await validateTransaction(tx, this.chainIdentification.id)\n return errors.length > 0 ? false : true\n })\n await this.pendingTransactionsLocalArchivist.insert(flattenHydratedTransactions(validTransactions))\n }, XyoPendingTransactionsService.MutexPriority.InsertNewTransactions)\n })\n }\n\n private async removeFinalizedTransactions(payloads: WithStorageMeta<Payload>[]) {\n return await this.removeTransactions(payloads, 'RemoveFinalizedTransactions')\n }\n\n private async removeRejectedTransactions(payloads: WithStorageMeta<Payload>[]) {\n return await this.removeTransactions(payloads, 'RemoveRejectedTransactions')\n }\n\n private async removeTransactions(\n payloads: WithStorageMeta<Payload>[],\n priority: keyof typeof XyoPendingTransactionsService.MutexPriority,\n ) {\n return await this.spanAsync(priority, async () => {\n return await this._updateCuratedPendingTransactionsArchivistMutex.runExclusive(async () => {\n const transactions = filterAs(payloads, asOptionalTransactionBoundWitnessWithStorageMeta)\n await this.pendingTransactionsLocalArchivist.delete(transactions.map(tx => tx._hash))\n }, XyoPendingTransactionsService.MutexPriority[priority])\n })\n }\n}\n","import { filterAs } from '@xylabs/array'\nimport { exists } from '@xylabs/exists'\nimport type { Hash } from '@xylabs/hex'\nimport type { ArchivistInstance } from '@xyo-network/archivist-model'\nimport type { BoundWitness } from '@xyo-network/boundwitness-model'\nimport { asOptionalBoundWitness } from '@xyo-network/boundwitness-model'\nimport { payloadSchemasContains } from '@xyo-network/boundwitness-validator'\nimport { BoundWitnessWrapper } from '@xyo-network/boundwitness-wrapper'\nimport type {\n BlockBoundWitness, ChainStakeIntent, Intent,\n} from '@xyo-network/xl1-protocol'\nimport { asOptionalChainStakeIntent, ChainStakeIntentSchema } from '@xyo-network/xl1-protocol'\n\nexport const getBlockSignedStakeDeclarations = async (block: BlockBoundWitness, archivist: ArchivistInstance, intent: Intent): Promise<ChainStakeIntent[]> => {\n // Get payloads in block\n const blockData = await archivist.get(block.payload_hashes)\n // Filter Payloads in block to BoundWitnesses\n const bwsFromBlock = filterAs(blockData, asOptionalBoundWitness)\n // Filter to BoundWitnesses with StakeIntent payloads\n const bwsFromBlockWithDeclarations = bwsFromBlock.filter(bw => payloadSchemasContains(bw, ChainStakeIntentSchema))\n // Filter to only valid signed BWs\n const validBlockBwsWithDeclarations = await filterToValidSignedBoundWitnesses(bwsFromBlockWithDeclarations)\n return (await Promise.all(validBlockBwsWithDeclarations.map(async (bw) => {\n // Get staked intent hashes from signed declarations\n const stakeIntentHashes = validBlockBwsWithDeclarations\n .flatMap(mapBoundWitnessToStakeIntentHashes)\n .filter(exists)\n // Get staked intent payloads\n const payloads = await archivist.get(stakeIntentHashes)\n // Filter payloads to staked intents\n const stakeIntents = filterAs(payloads, asOptionalChainStakeIntent)\n // that are producers\n .filter(p => p.intent === intent)\n // where the issuer of the intent is also the signer of this BW\n .filter(p => bw.addresses.includes(p.from))\n\n return stakeIntents\n }))).flat()\n}\n\nconst filterToValidSignedBoundWitnesses = async (bws: BoundWitness[]): Promise<BoundWitness[]> => {\n const validBwIndexes = await Promise.all(bws.map(bw => BoundWitnessWrapper.parse(bw).getValid()))\n return bws.filter((_, index) => validBwIndexes[index])\n}\n\nconst mapBoundWitnessToStakeIntentHashes = (bw: BoundWitness): (Hash | undefined)[] => {\n return bw.payload_schemas.map((schema, index) => schema === ChainStakeIntentSchema ? bw.payload_hashes[index] : undefined)\n}\n","import { filterAs } from '@xylabs/array'\nimport { assertEx } from '@xylabs/assert'\nimport {\n Address, asAddress, Hash,\n} from '@xylabs/hex'\nimport { ArchivistInstance, ArchivistNextOptions } from '@xyo-network/archivist-model'\nimport {\n analyzeChain, ChainStakeIntentAnalyzer,\n isChainSummaryStakeIntent,\n} from '@xyo-network/chain-analyze'\nimport {\n DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS,\n findFirstMatching, IntervalMap,\n SerializedIntervalMap,\n} from '@xyo-network/chain-utils'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport { Payload, WithStorageMeta } from '@xyo-network/payload-model'\nimport type {\n BaseServiceParams, EventingChainBlockNumberIterator, Intent,\n} from '@xyo-network/xl1-protocol'\nimport {\n asOptionalBlockBoundWitness, asOptionalBlockBoundWitnessWithStorageMeta,\n asOptionalChainIndexingServiceStateWithStorageMeta, asOptionalChainStakeIntent, ChainIndexingServiceState, ChainIndexingServiceStateSchema, ChainStakeViewer,\n isChainIndexingServiceState,\n StakeIntentService,\n} from '@xyo-network/xl1-protocol'\nimport { Mutex } from 'async-mutex'\nimport { LRUCache } from 'lru-cache'\n\nimport { BaseService, creatableService } from '../BaseService.ts'\n\nexport interface XyoStakeIntentServiceParams extends BaseServiceParams {\n chainArchivist?: ArchivistInstance\n chainIterator?: EventingChainBlockNumberIterator\n chainStakeViewer?: ChainStakeViewer\n stakeIntentStateArchivist?: ArchivistInstance\n}\n\n/**\n * The number of blocks to periodically persist state\n */\nconst STATE_PERSISTENCE_INTERVAL = 60n\n\nconst ACTIVE_STAKE_TTL = 1000 * 60 * 60 * 2 // 2 hours in milliseconds\nconst NO_ACTIVE_STAKE_TTL = 1000 * 2 // 2 seconds in milliseconds\nconst STAKE_CACHE_MAX_ENTRIES = 10_000\n\n@creatableService()\nexport class XyoStakeIntentService extends BaseService<XyoStakeIntentServiceParams> implements StakeIntentService {\n // TODO: Use hash instead of block number to handle chain reorgs\n protected _lastIndexedBlockHash: Hash | undefined = undefined\n // TODO: Interval tree per declaration (bank, validator, etc.)\n // NOTE: Ideally move to DataIntervalTree to handle declared\n // ranges as it enables range queries in O(min(n, k * log n)) time,\n // where k is the number of intervals in the output list time\n // Currently using set based because it's simpler, equivalent\n // in performance for small sets, and (most importantly) easily\n // persisted so we can recover state on restart.\n protected _producers: IntervalMap<Address> = new IntervalMap()\n protected _stakeCache = new LRUCache<Address, bigint>({ max: STAKE_CACHE_MAX_ENTRIES })\n protected _updateMutex = new Mutex()\n\n constructor(params: XyoStakeIntentServiceParams) {\n super(params)\n this.chainIterator.on('headUpdated', async () => {\n await this.updateIndex()\n })\n }\n\n protected get chainArchivist() {\n return assertEx(this.params.chainArchivist, () => 'chainArchivist not set')\n }\n\n protected get chainIterator() {\n return assertEx(this.params.chainIterator, () => 'chainIterator not set')\n }\n\n protected get chainStakeViewer() {\n return assertEx(this.params.chainStakeViewer, () => 'chainStakeViewer not set')\n }\n\n protected get stakeIntentStateArchivist() {\n return assertEx(this.params.stakeIntentStateArchivist, () => 'stakeIntentStateArchivist not set')\n }\n\n override async createHandler(): Promise<void> {\n const head = await this.chainIterator.head()\n const headHash = await PayloadBuilder.hash(head)\n if (head?.block === undefined) return\n await this.recoverState(headHash)\n await this.updateIndex(true)\n }\n\n async getDeclaredCandidateRanges(address: Address, intent: Intent): Promise<Readonly<Readonly<[number, number]>[]>> {\n await Promise.resolve()\n assertEx(intent === 'producer', () => `Error: Support not yet added for intent ${intent}`)\n const results = this._producers.get(address)\n return results ?? []\n }\n\n async getDeclaredCandidatesForBlock(block: number, intent: Intent): Promise<Address[]> {\n return await this.spanAsync('getDeclaredCandidatesForBlock', async () => {\n assertEx(intent === 'producer', () => `Error: Support not yet added for intent ${intent}`)\n const results = this._producers.findAllContaining(block)\n const candidates = [...results]\n const validCandidates = await this.filterToValidStake(candidates, this.chainStakeViewer)\n return validCandidates\n })\n }\n\n async isStakedForBlock(block: number, intent: Intent, address: Address): Promise<boolean> {\n const candidates = await this.getDeclaredCandidatesForBlock(block, intent)\n return candidates.includes(address)\n }\n\n private async filterToValidStake(\n candidates: Address[],\n chainStakeViewer: ChainStakeViewer,\n requiredMinimumStake: bigint = 1n,\n ): Promise<Address[]> {\n type CandidateStake = { candidate: Address; stake: bigint }\n\n // Find the stake for each candidate\n const candidatesWithStake: CandidateStake[] = await Promise.all(\n candidates.map(async (candidate) => {\n // Check if the stake is already cached\n const stake = this._stakeCache.get(candidate)\n if (stake === undefined) {\n // Fetch from chainStakeViewer if not cached\n const activeStake = await chainStakeViewer.activeByAddressStaked(`${candidate}`)\n if (activeStake > 0n) {\n // Store result in cache\n this._stakeCache.set(candidate, activeStake, { ttl: ACTIVE_STAKE_TTL })\n } else {\n this._stakeCache.set(candidate, activeStake, { ttl: NO_ACTIVE_STAKE_TTL })\n }\n return { candidate, stake: activeStake }\n } else {\n return { candidate, stake }\n }\n }),\n )\n\n // Filter out candidates whose stake is greater than or equal to the required minimum\n return candidatesWithStake\n .filter(({ stake }) => stake >= requiredMinimumStake)\n .map(({ candidate }) => candidate)\n }\n\n private async persistState(current: Hash): Promise<void> {\n const state = this._producers.serialize()\n const payload = new PayloadBuilder<ChainIndexingServiceState<SerializedIntervalMap>>({ schema: ChainIndexingServiceStateSchema })\n .fields({ endBlockHash: current, state })\n .build()\n await this.stakeIntentStateArchivist.insert([payload])\n }\n\n private async recoverState(current: Hash): Promise<void> {\n const currentBlock = assertEx(asOptionalBlockBoundWitness((await this.chainArchivist.get([current]))?.[0]), () => `Block ${current} not found`)\n const currentBlockNum = currentBlock.block\n // Find last state before current head (in case of rollback, we indexed past it on an uncle chain, etc.)\n const opts: ArchivistNextOptions = { ...DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS }\n while (true) {\n const predicate = (p: WithStorageMeta<Payload>) => {\n const state = asOptionalChainIndexingServiceStateWithStorageMeta(p)\n return state ? true : false\n }\n const state = await findFirstMatching(this.stakeIntentStateArchivist, predicate, opts)\n if (isChainIndexingServiceState<SerializedIntervalMap>(state)) {\n const indexed = (await this.chainArchivist.get([state.endBlockHash]))?.[0]\n const indexedBlock = asOptionalBlockBoundWitnessWithStorageMeta(indexed)\n if (indexedBlock) {\n const indexedBlockNum = indexedBlock.block\n if (indexedBlockNum <= currentBlockNum) {\n const data = state.state as SerializedIntervalMap\n this._producers = new IntervalMap(data)\n this._lastIndexedBlockHash = indexedBlock._hash\n break\n }\n }\n } else {\n // No state found, start from genesis\n break\n }\n opts.open = true\n }\n }\n\n private async updateIndex(displayProgress = false): Promise<void> {\n if (this._updateMutex.isLocked()) {\n return\n }\n await this._updateMutex.runExclusive(async () => {\n return await this.spanAsync('updateIndex', async () => {\n const currentHead = await this.chainIterator.head()\n const currentHeadHash = await PayloadBuilder.hash(currentHead)\n const result = await analyzeChain(this.chainArchivist, [new ChainStakeIntentAnalyzer('producer')], currentHeadHash, this._lastIndexedBlockHash)\n const signedDeclarations = filterAs(result.find(isChainSummaryStakeIntent)?.intents ?? [], asOptionalChainStakeIntent)\n if (currentHead.block === undefined) return\n const currentHeadBlockNum = currentHead.block\n if (displayProgress) this.logger?.info(`Updating index through 0x${currentHeadBlockNum}`)\n for (const signedDeclaration of signedDeclarations) {\n const { exp, nbf } = signedDeclaration\n const start = nbf\n const stop = exp\n const address = asAddress(signedDeclaration?.from)\n if (start !== undefined && stop !== undefined && address !== undefined) {\n this._producers.insert(address, start, stop)\n }\n }\n /*\n if (index % STATE_PERSISTENCE_INTERVAL === 0n) {\n if (displayProgress) this.logger?.info(`Persisting state at block ${index}`)\n await this.persistState(await PayloadBuilder.hash(block))\n }\n */\n this._lastIndexedBlockHash = currentHeadHash\n })\n })\n }\n}\n","import { Base } from '@xylabs/base'\nimport type { Address } from '@xylabs/hex'\nimport { toAddress } from '@xylabs/hex'\nimport type { Promisable } from '@xylabs/promise'\nimport type { StakedXyoChain } from '@xyo-network/typechain'\nimport { StakedXyoChain__factory as StakedXyoChainFactory } from '@xyo-network/typechain'\nimport type { BaseServiceParams, ChainService } from '@xyo-network/xl1-protocol'\nimport { getAddress } from 'ethers/address'\nimport type { ContractRunner } from 'ethers/providers'\n\nexport interface EvmChainServiceParams extends BaseServiceParams {\n contract: StakedXyoChain\n id: Address\n runner: ContractRunner\n}\n\n/**\n * A class that represents a chain stake as backed by an EVM smart contract\n */\nexport class EvmChainService extends Base<EvmChainServiceParams> implements ChainService {\n private _contract: StakedXyoChain\n\n protected constructor(params: EvmChainServiceParams) {\n super(params)\n this._contract = params.contract\n }\n\n get id(): Address {\n return this.params.id\n }\n\n get runner(): ContractRunner {\n return this.params.runner\n }\n\n static create({\n id, runner, logger, traceProvider, meterProvider,\n }: Omit<EvmChainServiceParams, 'contract'>): Promisable<EvmChainService> {\n const contractAddress = getAddress(id)\n const contract: StakedXyoChain = StakedXyoChainFactory.connect(contractAddress, runner)\n return new this({\n id, contract, runner, logger, traceProvider, meterProvider,\n })\n }\n\n async active(): Promise<bigint> {\n return await this._contract.active()\n }\n\n async activeByAddressStaked(address: string): Promise<bigint> {\n return await this._contract.activeByAddressStaked(getAddress(address))\n }\n\n async activeByStaker(address: string): Promise<bigint> {\n return await this._contract.activeByStaker(getAddress(address))\n }\n\n async addStake(staked: string, amount: bigint): Promise<boolean> {\n const result = await this._contract.addStake(getAddress(staked), amount)\n await result.wait()\n return true\n }\n\n async chainId(): Promise<Address> {\n return toAddress(await this._contract.chainId())\n }\n\n async forkedAtBlockNumber(): Promise<bigint> {\n return await this._contract.forkedAtBlockNumber()\n }\n\n async forkedAtHash(): Promise<bigint> {\n return await this._contract.forkedAtHash()\n }\n\n async forkedChainId(): Promise<Address> {\n return toAddress(await this._contract.forkedChainId())\n }\n\n async minWithdrawalBlocks(): Promise<bigint> {\n return await this._contract.minWithdrawalBlocks()\n }\n\n async pending(): Promise<bigint> {\n return await this._contract.pending()\n }\n\n async pendingByStaker(staker: string): Promise<bigint> {\n return await this._contract.pendingByStaker(getAddress(staker))\n }\n\n async removeStake(slot: bigint): Promise<boolean> {\n const result = await this._contract.removeStake(slot)\n await result.wait()\n return true\n }\n\n async rewardsContract(): Promise<string> {\n return await this._contract.rewardsContract()\n }\n\n async stakingTokenAddress(): Promise<string> {\n return await this._contract.stakingTokenAddress()\n }\n\n async withdrawStake(slot: bigint): Promise<boolean> {\n const result = await this._contract.withdrawStake(slot)\n await result.wait()\n return true\n }\n\n async withdrawn(): Promise<bigint> {\n return await this._contract.withdrawn()\n }\n\n async withdrawnByStaker(staker: string): Promise<bigint> {\n return await this._contract.withdrawnByStaker(getAddress(staker))\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport type { BaseParams } from '@xylabs/base'\nimport { BaseEmitter } from '@xylabs/events'\nimport { isDefined, isNull } from '@xylabs/typeof'\nimport type { ArchivistInstance } from '@xyo-network/archivist-model'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport type {\n BlockBoundWitness, ChainIdentification,\n ChainIteratorEventData,\n EventingChainBlockNumberIterator,\n XyoChainIteratorParams,\n} from '@xyo-network/xl1-protocol'\nimport {\n asBlockBoundWitness, asOptionalBlockBoundWitness,\n isBlockBoundWitness,\n} from '@xyo-network/xl1-protocol'\nimport { LRUCache } from 'lru-cache'\n\nexport class XyoChainBlockNumberIterator extends BaseEmitter<BaseParams, ChainIteratorEventData> implements EventingChainBlockNumberIterator {\n protected _blocksByBlockNumber = new LRUCache<number, BlockBoundWitness>({ max: 10_000 })\n protected _chainArchivist: ArchivistInstance\n protected _chainInformation: ChainIdentification\n protected _head: BlockBoundWitness\n\n protected constructor(params: XyoChainIteratorParams) {\n super({})\n const { chainArchivist: archivist, head } = params\n this._chainArchivist = archivist\n this._head = head\n this._chainInformation = { id: head.chain }\n }\n\n get archivist(): ArchivistInstance { return this._chainArchivist }\n\n get chainIdentification(): ChainIdentification { return this._chainInformation }\n\n static async create(params: XyoChainIteratorParams): Promise<XyoChainBlockNumberIterator> {\n await Promise.resolve()\n return new XyoChainBlockNumberIterator(params)\n }\n\n async get(block: number): Promise<BlockBoundWitness> {\n // Bail early if the block requested is newer than the current head\n assertEx(this._head.block >= block, () => `Block requested is newer than the current head [${block}]`)\n const cached = this._blocksByBlockNumber.get(block)\n if (cached) return cached\n // Start at the current head and traverse backwards until the requested block is found\n const startingBlock = this._head\n const currentBlockHash = await PayloadBuilder.hash(startingBlock)\n let currentBlock = (await this._chainArchivist.get([currentBlockHash])).at(0)\n while (isDefined(currentBlock)) {\n assertEx(asBlockBoundWitness(currentBlock), () => `Expected hash to be a block bound witness [${currentBlock?._hash}]`)\n if (isBlockBoundWitness(currentBlock)) {\n this._blocksByBlockNumber.set(currentBlock.block, currentBlock)\n if (currentBlock.block === block) {\n return currentBlock\n }\n const { previous } = currentBlock\n if (isNull(previous)) break\n currentBlock = (await this._chainArchivist.get([previous])).at(0)\n }\n }\n throw new Error(`Block not found: ${block}`)\n }\n\n async head(): Promise<BlockBoundWitness> {\n return await Promise.resolve(this._head)\n }\n\n async next(block: number): Promise<BlockBoundWitness | undefined> {\n const currentBlock = block\n const nextBlockNumber = currentBlock + 1\n return await this.get(nextBlockNumber)\n }\n\n // TODO: Decide on inclusive/exclusive (probably need inclusive to account for chain head)\n // and then communicate via method name and documentation\n async previous(block: number | undefined = undefined, count: number = 1): Promise<BlockBoundWitness[]> {\n const results: BlockBoundWitness[] = []\n let currentBlock: BlockBoundWitness | undefined = isDefined(block) ? (await this.get(block)) : this._head\n while (currentBlock && results.length < count) {\n if (isBlockBoundWitness(currentBlock)) {\n results.push(currentBlock)\n const { previous } = currentBlock\n if (isNull(previous)) break\n const nextBlock = await this._chainArchivist.get([previous])\n currentBlock = asOptionalBlockBoundWitness(nextBlock[0])\n } else {\n const hash = PayloadBuilder.hash(currentBlock)\n assertEx(asBlockBoundWitness(currentBlock), () => `Expected hash to be a block bound witness [${hash}]`)\n }\n }\n return results\n }\n\n async updateHead(head: BlockBoundWitness): Promise<void> {\n // Async to allow for re-indexing, etc.\n await Promise.resolve()\n this._head = head\n void this.emit('headUpdated', { blocks: [head] })\n }\n}\n"],"mappings":"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","names":["assertEx","toHex","analyzeChain","BalanceAnalyzer","isChainSummaryBalances","toPositiveBigInt","BaseEmitter","span","spanAsync","Mutex","BaseService","BaseEmitter","singletonInitMutex","Mutex","singletons","globalThis","name","constructor","create","params","result","Error","createHandler","initSingleton","runExclusive","span","fn","tracer","spanAsync","BaseAccountableService","creatableService","XyoChainAccountBalanceService","BaseService","_balances","_previousHead","chainArchivist","assertEx","params","getBalance","address","toPositiveBigInt","positive","toHex","getBalances","result","entries","Object","balance","sync","head","analysis","analyzeChain","BalanceAnalyzer","tracer","find","isChainSummaryBalances","balances","BaseEthProvider","eth_accounts","Error","eth_blockNumber","eth_call","_transaction","_blockNumber","eth_clearSubscriptions","_keepSyncing","eth_coinbase","eth_compileLLL","_code","eth_compileSerpent","eth_compileSolidity","eth_estimateGas","eth_feeHistory","_blockCount","_newestBlock","_rewardPercentiles","eth_gasPrice","eth_getBalance","_address","eth_getBlockByHash","_blockHash","_hydrated","eth_getBlockByNumber","eth_getBlockTransactionCountByHash","eth_getBlockTransactionCountByNumber","eth_getCode","eth_getCompilers","eth_getFilterChanges","_filterIdentifier","eth_getFilterLogs","eth_getLogs","_filter","eth_getStorageAt","_storageSlot","eth_getTransactionByBlockHashAndIndex","_transactionIndex","eth_getTransactionByBlockNumberAndIndex","eth_getTransactionByHash","_transactionHash","eth_getTransactionCount","eth_getTransactionReceipt","eth_getUncleByBlockHashAndIndex","_uncleIndex","eth_getUncleByBlockNumberAndIndex","eth_getUncleCountByBlockHash","eth_getUncleCountByBlockNumber","eth_getWork","eth_hashrate","eth_maxPriorityFeePerGas","eth_mining","eth_newBlockFilter","eth_newFilter","eth_newPendingTransactionFilter","eth_protocolVersion","eth_sendRawTransaction","eth_sendTransaction","eth_sign","_message","eth_signTransaction","eth_submitHashrate","_hashRate","_id","eth_submitWork","_nonce","_hash","_digest","eth_subscribe","_params","eth_syncing","eth_uninstallFilter","eth_unsubscribe","_subscriptionId","assertEx","toHex","isUndefined","FixedPercentageBlockRewardDiviner","FixedPercentageBlockRewardDivinerConfigSchema","buildBlock","PayloadBuilder","asBlockBoundWitness","BlockNumberSchema","ChainStakeIntentSchema","hexFromBigInt","HydratedTransactionWrapper","TransferSchema","generateTransactionTransfers","address","transactions","txs","Promise","all","map","tx","HydratedTransactionWrapper","parse","txCosts","existingItem","find","addr","boundWitness","from","fees","base","push","payloads","amount","payload","schema","TransferSchema","epoch","Date","now","transfers","hexFromBigInt","DEFAULT_BLOCK_SIZE","XYO_PRODUCER_RESTAKE_DURATION","XYO_PRODUCER_RESTAKE_WINDOW","XyoBlockProducer","BaseService","_blockRewardDiviner","DefaultBlockSize","address","account","assertEx","params","chainFinalizedArchivist","chainInfo","chainInformation","electionService","pendingTransactions","pendingTransactionsService","rejectedTransactionsArchivist","rewardAddress","rewardService","stakeIntentService","validateHydratedBlockState","next","head","chain","id","leaders","getCreatorCommitteeForNextBlock","proposeNextValidBlock","getBlockRewardTransfer","block","FixedPercentageBlockRewardDiviner","create","blockRewardService","config","rewardPercentageRatio","schema","FixedPercentageBlockRewardDivinerConfigSchema","blockHex","toHex","blockId","PayloadBuilder","BlockNumberSchema","fields","build","rewards","divine","reward","getProducerRedeclaration","redeclareIntent","process","env","XYO_PRODUCER_REDECLARE_INTENT","isUndefined","ranges","getDeclaredCandidateRanges","lastRange","toSorted","a","b","at","currentDeclarationEnd","currentBlock","timeToProducerExpiration","intent","ChainStakeIntentSchema","from","nbf","exp","spanAsync","previousBlock","asBlockBoundWitness","nextBlock","nextBlockTransactions","getPendingTransactions","_hash","blockPayloads","producerRedeclarationPayload","push","length","rewardTransferPayload","transactionTransfers","generateTransactionTransfers","buildBlock","console","log","errors","logger","error","rejectedTransactions","insert","assertEx","XyoChainRewards__factory","XyoChainRewardsFactory","toEthAddress","EvmBlockRewardService","BaseService","_contractAddress","chainService","assertEx","params","contractAddress","provider","createHandler","rewardsContract","getRewardForBlock","blockNumber","contract","XyoChainRewardsFactory","connect","toEthAddress","calcBlockReward","assertEx","toFixedPoint","rewardFromBlockNumber","XyoBlockRewardService","BaseService","rewardFromBlockNumber","constructor","creatorReward","toFixedPoint","initialStepReward","minRewardPerBlock","stepFactorDenominator","stepFactorNumerator","stepSize","assertEx","params","initialReward","getRewardForBlock","blockNumber","assertEx","PayloadBuilder","addStorageMeta","tx","payloads","PayloadBuilder","XyoValidator","BaseService","address","account","assertEx","params","chainFinalizedArchivist","chainInfo","chainInformation","electionService","pendingTransactions","rewardService","validatePendingBlock","_block","validatePendingTransaction","hydratedTransaction","get","_hash","length","Promise","resolve","assertEx","hexToLast4BytesInt","shuffleWithSeed","PayloadBuilder","XyoElectionService","BaseService","constructor","params","chainIterator","assertEx","chainStakeViewer","stakeIntentService","getCreatorCommitteeForNextBlock","current","spanAsync","nextBlock","block","candidates","getDeclaredCandidatesForBlock","previousBlockHash","PayloadBuilder","hash","generateCreatorCommittee","maxSize","creators","Set","seed","hexToLast4BytesInt","creatorArray","shuffleWithSeed","slice","ValueType","filterAs","filterAsync","assertEx","exists","forget","MemoryArchivist","validateTransaction","asOptionalTransactionBoundWitnessWithStorageMeta","flattenHydratedTransactions","tryHydrateTransaction","Mutex","XyoPendingTransactionsService","BaseService","MutexPriority","InsertNewTransactions","ReadTransactions","RemoveRejectedTransactions","RemoveFinalizedTransactions","_countPendingTransactionsMutex","Mutex","_curatedPendingTransactionsArchivist","_pendingTransactionsCount","_updateCuratedPendingTransactionsArchivistMutex","chainArchivist","assertEx","params","chainIdentification","pendingTransactionsArchivist","pendingTransactionsCount","forget","countPendingTransactions","pendingTransactionsLocalArchivist","rejectedTransactionsArchivist","createHandler","MemoryArchivist","create","account","on","payloads","insertNewTransactions","removeFinalizedTransactions","removeRejectedTransactions","pendingTransactionsGauge","meter","createObservableGauge","description","valueType","ValueType","INT","addCallback","observer","observe","getPendingTransactions","head","limit","spanAsync","runExclusive","foundPendingTransactions","cursor","length","next","order","at","_sequence","transactions","map","payload","asOptionalTransactionBoundWitnessWithStorageMeta","filter","exists","push","hydratedTransactions","Promise","all","tx","tryHydrateTransaction","_hash","isLocked","pendingTransactions","filterAs","filterAlreadyFinalizedTransactions","incomingTransactions","incomingTransactionHashes","finalizedTransactions","get","finalizedTransactionHashes","Set","item","nonFinalizedTransactions","has","unprocessedTransactions","hydratedUnprocessedTransactions","validTransactions","filterAsync","errors","validateTransaction","id","insert","flattenHydratedTransactions","removeTransactions","priority","delete","filterAs","exists","asOptionalBoundWitness","payloadSchemasContains","BoundWitnessWrapper","asOptionalChainStakeIntent","ChainStakeIntentSchema","getBlockSignedStakeDeclarations","block","archivist","intent","blockData","get","payload_hashes","bwsFromBlock","filterAs","asOptionalBoundWitness","bwsFromBlockWithDeclarations","filter","bw","payloadSchemasContains","ChainStakeIntentSchema","validBlockBwsWithDeclarations","filterToValidSignedBoundWitnesses","Promise","all","map","stakeIntentHashes","flatMap","mapBoundWitnessToStakeIntentHashes","exists","payloads","stakeIntents","asOptionalChainStakeIntent","p","addresses","includes","from","flat","bws","validBwIndexes","BoundWitnessWrapper","parse","getValid","_","index","payload_schemas","schema","undefined","filterAs","assertEx","asAddress","analyzeChain","ChainStakeIntentAnalyzer","isChainSummaryStakeIntent","DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS","findFirstMatching","IntervalMap","PayloadBuilder","asOptionalBlockBoundWitness","asOptionalBlockBoundWitnessWithStorageMeta","asOptionalChainIndexingServiceStateWithStorageMeta","asOptionalChainStakeIntent","ChainIndexingServiceStateSchema","isChainIndexingServiceState","Mutex","LRUCache","ACTIVE_STAKE_TTL","NO_ACTIVE_STAKE_TTL","STAKE_CACHE_MAX_ENTRIES","XyoStakeIntentService","BaseService","_lastIndexedBlockHash","undefined","_producers","IntervalMap","_stakeCache","LRUCache","max","_updateMutex","Mutex","constructor","params","chainIterator","on","updateIndex","chainArchivist","assertEx","chainStakeViewer","stakeIntentStateArchivist","createHandler","head","headHash","PayloadBuilder","hash","block","recoverState","getDeclaredCandidateRanges","address","intent","Promise","resolve","results","get","getDeclaredCandidatesForBlock","spanAsync","findAllContaining","candidates","validCandidates","filterToValidStake","isStakedForBlock","includes","requiredMinimumStake","candidatesWithStake","all","map","candidate","stake","activeStake","activeByAddressStaked","set","ttl","filter","persistState","current","state","serialize","payload","schema","ChainIndexingServiceStateSchema","fields","endBlockHash","build","insert","currentBlock","asOptionalBlockBoundWitness","currentBlockNum","opts","DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS","predicate","p","asOptionalChainIndexingServiceStateWithStorageMeta","findFirstMatching","isChainIndexingServiceState","indexed","indexedBlock","asOptionalBlockBoundWitnessWithStorageMeta","indexedBlockNum","data","_hash","open","displayProgress","isLocked","runExclusive","currentHead","currentHeadHash","result","analyzeChain","ChainStakeIntentAnalyzer","signedDeclarations","filterAs","find","isChainSummaryStakeIntent","intents","asOptionalChainStakeIntent","currentHeadBlockNum","logger","info","signedDeclaration","exp","nbf","start","stop","asAddress","from","Base","toAddress","StakedXyoChain__factory","StakedXyoChainFactory","getAddress","EvmChainService","Base","_contract","params","contract","id","runner","create","logger","traceProvider","meterProvider","contractAddress","getAddress","StakedXyoChainFactory","connect","active","activeByAddressStaked","address","activeByStaker","addStake","staked","amount","result","wait","chainId","toAddress","forkedAtBlockNumber","forkedAtHash","forkedChainId","minWithdrawalBlocks","pending","pendingByStaker","staker","removeStake","slot","rewardsContract","stakingTokenAddress","withdrawStake","withdrawn","withdrawnByStaker","assertEx","BaseEmitter","isDefined","isNull","PayloadBuilder","asBlockBoundWitness","asOptionalBlockBoundWitness","isBlockBoundWitness","LRUCache","XyoChainBlockNumberIterator","BaseEmitter","_blocksByBlockNumber","LRUCache","max","_chainArchivist","_chainInformation","_head","params","chainArchivist","archivist","head","id","chain","chainIdentification","create","Promise","resolve","get","block","assertEx","cached","startingBlock","currentBlockHash","PayloadBuilder","hash","currentBlock","at","isDefined","asBlockBoundWitness","_hash","isBlockBoundWitness","set","previous","isNull","Error","next","nextBlockNumber","undefined","count","results","length","push","nextBlock","asOptionalBlockBoundWitness","updateHead","emit","blocks"]}
1
+ {"version":3,"sources":["../../src/AccountBalance/XyoChainAccountBalanceService.ts","../../src/BaseService.ts","../../src/BaseEthProvider.ts","../../src/BlockProducer/XyoBlockProducer.ts","../../src/BlockProducer/generateTransactionTransfers.ts","../../src/BlockReward/EvmBlockRewardService.ts","../../src/BlockReward/XyoBlockRewardService.ts","../../src/ChainValidator/XyoValidator.ts","../../src/Election/XyoElectionService.ts","../../src/PendingTransactions/PendingTransactions.ts","../../src/StakeIntent/lib/getBlockSignedStakeDeclarations.ts","../../src/StakeIntent/XyoStakeIntentService.ts","../../src/Staker/Evm/Evm.ts","../../src/XyoChainBlockNumberIterator.ts"],"sourcesContent":["import { assertEx } from '@xylabs/assert'\nimport {\n Address, Hash, Hex,\n toHex,\n} from '@xylabs/hex'\nimport {\n analyzeChain, BalanceAnalyzer, isChainSummaryBalances,\n} from '@xyo-network/chain-analyze'\nimport { SignedBigInt, toPositiveBigInt } from '@xyo-network/chain-protocol'\nimport {\n AccountBalanceService, BaseServiceParams,\n ChainServiceCollection,\n} from '@xyo-network/xl1-protocol'\n\nimport { BaseService, creatableService } from '../BaseService.ts'\n\nexport type ChainAccountBalanceServiceParams = BaseServiceParams<Partial<Pick<ChainServiceCollection, 'chainArchivist'>>>\n\n@creatableService()\nexport class XyoChainAccountBalanceService extends BaseService<ChainAccountBalanceServiceParams> implements AccountBalanceService {\n private _balances: Record<Address, SignedBigInt> = {}\n private _previousHead: Hash | null = null\n\n protected get chainArchivist() {\n return assertEx(this.params.chainArchivist, () => 'chainArchivist is required')\n }\n\n getBalance(address: Address): Hex {\n return toPositiveBigInt(this._balances[address] ?? { positive: toHex(0n) }).positive\n }\n\n getBalances(): Record<Address, Hex> {\n const result: Record<Address, Hex> = {}\n const entries = Object.entries(this._balances) as [Address, SignedBigInt][]\n for (const [address, balance] of entries) {\n result[address] = toPositiveBigInt(balance).positive\n }\n return result\n }\n\n async sync(head: Hash): Promise<void> {\n const analysis = await analyzeChain(\n this.chainArchivist,\n [new BalanceAnalyzer()],\n head,\n this._previousHead,\n -1n,\n this.tracer,\n )\n this._balances = assertEx(analysis.find(isChainSummaryBalances)?.balances, () => 'Failed to sync balances')\n }\n}\n","import { BaseEmitter } from '@xylabs/events'\nimport type { Promisable } from '@xylabs/promise'\nimport { span, spanAsync } from '@xyo-network/chain-utils'\nimport type {\n BaseAccountableServiceParams, BaseServiceParams, Service,\n} from '@xyo-network/xl1-protocol'\nimport { Mutex } from 'async-mutex'\n\ndeclare global {\n var xyoServiceSingletons: Record<string, unknown>\n}\n\nexport class BaseService<TParams extends BaseServiceParams = BaseServiceParams> extends BaseEmitter<TParams> {\n private static singletonInitMutex = new Mutex()\n\n static get singletons() {\n return globalThis['xyoServiceSingletons'] ?? (globalThis['xyoServiceSingletons'] = {})\n }\n\n get name() {\n return this.constructor.name\n }\n\n static async create<TService extends BaseService<TParams>, TParams extends BaseServiceParams = TService['params']>(\n this: CreatableService<TService>,\n params: TParams,\n ): Promise<TService> {\n const result = new this(params)\n if (result.name === 'BaseService') throw new Error('Cannot create BaseService')\n await result.createHandler()\n return result\n }\n\n static initSingleton<TService extends BaseService<TParams>, TParams extends BaseServiceParams>(params: TParams) {\n if (this.singletons[this.name]) throw new Error(`Singleton already initialized for ${this.name}`)\n return this.singletonInitMutex.runExclusive(async () => {\n return await this.create(params) as TService\n })\n }\n\n createHandler(): Promisable<void> {\n return\n }\n\n span<T>(name: string, fn: () => T): T {\n return span(name, fn, this.tracer)\n }\n\n async spanAsync<T>(name: string, fn: () => Promise<T>): Promise<T> {\n return await spanAsync(name, fn, this.tracer)\n }\n}\n\nexport abstract class BaseAccountableService<\n TParams extends BaseAccountableServiceParams = BaseAccountableServiceParams,\n> extends BaseService<TParams> {\n // Base class for services that have an account\n}\n\nexport interface CreatableService<T extends BaseService = BaseService> extends Service {\n new(params: T['params']): T\n create<T extends BaseService>(this: CreatableService<T>, params: T['params']): Promisable<T>\n}\n\nexport function creatableService<T extends BaseService = BaseService>() {\n return <U extends CreatableService<T>>(constructor: U) => {\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n constructor\n }\n}\n","import type {\n Address, BlockAPI,\n BlockNumberOrTag,\n CompileResultAPI,\n EthExecutionAPI,\n FeeHistoryResultAPI,\n Filter,\n FilterResultsAPI,\n HexString, HexString8Bytes,\n HexString32Bytes,\n HexString256Bytes,\n HexStringBytes,\n SignedTransactionInfoAPI,\n SyncingStatusAPI,\n TransactionCallAPI,\n TransactionInfoAPI,\n TransactionReceiptAPI,\n TransactionWithSenderAPI,\n Uint,\n Uint256,\n} from 'web3-types'\n\nexport class BaseEthProvider implements EthExecutionAPI {\n eth_accounts(): Address[] {\n throw new Error('Method not implemented.')\n }\n\n eth_blockNumber(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_call(_transaction: TransactionCallAPI, _blockNumber: BlockNumberOrTag): HexStringBytes {\n throw new Error('Method not implemented.')\n }\n\n eth_clearSubscriptions(_keepSyncing?: boolean): void {\n throw new Error('Method not implemented.')\n }\n\n eth_coinbase(): Address {\n throw new Error('Method not implemented.')\n }\n\n eth_compileLLL(_code: string): HexStringBytes {\n throw new Error('Method not implemented.')\n }\n\n eth_compileSerpent(_code: string): HexStringBytes {\n throw new Error('Method not implemented.')\n }\n\n eth_compileSolidity(_code: string): CompileResultAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_estimateGas(_transaction: Partial<TransactionWithSenderAPI>, _blockNumber: BlockNumberOrTag): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_feeHistory(_blockCount: Uint, _newestBlock: BlockNumberOrTag, _rewardPercentiles: number[]): FeeHistoryResultAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_gasPrice(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getBalance(_address: Address, _blockNumber: BlockNumberOrTag): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getBlockByHash(_blockHash: HexString32Bytes, _hydrated: boolean): BlockAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getBlockByNumber(_blockNumber: BlockNumberOrTag, _hydrated: boolean): BlockAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getBlockTransactionCountByHash(_blockHash: HexString32Bytes): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getBlockTransactionCountByNumber(_blockNumber: BlockNumberOrTag): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getCode(_address: Address, _blockNumber: BlockNumberOrTag): HexStringBytes {\n throw new Error('Method not implemented.')\n }\n\n eth_getCompilers(): string[] {\n throw new Error('Method not implemented.')\n }\n\n eth_getFilterChanges(_filterIdentifier: Uint): FilterResultsAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getFilterLogs(_filterIdentifier: Uint): FilterResultsAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getLogs(_filter: Filter): FilterResultsAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getStorageAt(_address: Address, _storageSlot: Uint256, _blockNumber: BlockNumberOrTag): HexStringBytes {\n throw new Error('Method not implemented.')\n }\n\n eth_getTransactionByBlockHashAndIndex(_blockHash: HexString32Bytes, _transactionIndex: Uint): TransactionInfoAPI | undefined {\n throw new Error('Method not implemented.')\n }\n\n eth_getTransactionByBlockNumberAndIndex(_blockNumber: BlockNumberOrTag, _transactionIndex: Uint): TransactionInfoAPI | undefined {\n throw new Error('Method not implemented.')\n }\n\n eth_getTransactionByHash(_transactionHash: HexString32Bytes): TransactionInfoAPI | undefined {\n throw new Error('Method not implemented.')\n }\n\n eth_getTransactionCount(_address: Address, _blockNumber: BlockNumberOrTag): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getTransactionReceipt(_transactionHash: HexString32Bytes): TransactionReceiptAPI | undefined {\n throw new Error('Method not implemented.')\n }\n\n eth_getUncleByBlockHashAndIndex(_blockHash: HexString32Bytes, _uncleIndex: Uint): BlockAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getUncleByBlockNumberAndIndex(_blockNumber: BlockNumberOrTag, _uncleIndex: Uint): BlockAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getUncleCountByBlockHash(_blockHash: HexString32Bytes): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getUncleCountByBlockNumber(_blockNumber: BlockNumberOrTag): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getWork(): [HexString32Bytes, HexString32Bytes, HexString32Bytes] {\n throw new Error('Method not implemented.')\n }\n\n eth_hashrate(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_maxPriorityFeePerGas(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_mining(): boolean {\n throw new Error('Method not implemented.')\n }\n\n eth_newBlockFilter(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_newFilter(_filter: Filter): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_newPendingTransactionFilter(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_protocolVersion(): string {\n throw new Error('Method not implemented.')\n }\n\n eth_sendRawTransaction(_transaction: HexStringBytes): HexString32Bytes {\n throw new Error('Method not implemented.')\n }\n\n eth_sendTransaction(_transaction: TransactionWithSenderAPI | Partial<TransactionWithSenderAPI>): HexString32Bytes {\n throw new Error('Method not implemented.')\n }\n\n eth_sign(_address: Address, _message: HexStringBytes): HexString256Bytes {\n throw new Error('Method not implemented.')\n }\n\n eth_signTransaction(_transaction: TransactionWithSenderAPI | Partial<TransactionWithSenderAPI>): HexStringBytes | SignedTransactionInfoAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_submitHashrate(_hashRate: HexString32Bytes, _id: HexString32Bytes): boolean {\n throw new Error('Method not implemented.')\n }\n\n eth_submitWork(_nonce: HexString8Bytes, _hash: HexString32Bytes, _digest: HexString32Bytes): boolean {\n throw new Error('Method not implemented.')\n }\n\n eth_subscribe(..._params: ['newHeads'] | ['newPendingTransactions'] | ['syncing'] | ['logs', { address?: HexString; topics?: HexString[] }]): HexString {\n throw new Error('Method not implemented.')\n }\n\n eth_syncing(): SyncingStatusAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_uninstallFilter(_filterIdentifier: Uint): boolean {\n throw new Error('Method not implemented.')\n }\n\n eth_unsubscribe(_subscriptionId: HexString): HexString {\n throw new Error('Method not implemented.')\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { exists } from '@xylabs/exists'\nimport {\n Address, hexToBigInt, toHex,\n} from '@xylabs/hex'\nimport { isUndefined } from '@xylabs/typeof'\nimport { ArchivistInstance, ReadArchivist } from '@xyo-network/archivist-model'\nimport {\n BlockRewardDiviner, FixedPercentageBlockRewardDiviner, FixedPercentageBlockRewardDivinerConfigSchema,\n} from '@xyo-network/chain-modules'\nimport { buildBlock } from '@xyo-network/chain-protocol'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport { WithStorageMeta } from '@xyo-network/payload-model'\nimport {\n AccountBalanceService,\n AllowedBlockPayload, asBlockBoundWitness, BlockBoundWitness, BlockNumber, BlockNumberSchema, BlockProducer, ChainStakeIntent, ChainStakeIntentSchema,\n HydratedBlock, PendingTransactionsService, StakeIntentService, Transfer,\n} from '@xyo-network/xl1-protocol'\n\nimport { BaseService, creatableService } from '../BaseService.ts'\nimport { XyoValidatorParams } from '../ChainValidator/index.ts'\nimport { generateTransactionTransfers } from './generateTransactionTransfers.ts'\n\n/**\n * The default block size for a block\n */\nexport const DEFAULT_BLOCK_SIZE = 10\n\n// /**\n// * The amount of time for which a producer will restake their intent\n// */\nexport const XYO_PRODUCER_RESTAKE_DURATION = 10_000\n\n/**\n * The number of blocks within which a producer will redeclare\n * their intent to produce blocks\n */\nexport const XYO_PRODUCER_RESTAKE_WINDOW = 500n\n\nexport interface XyoBlockProducerParams extends XyoValidatorParams {\n accountBalanceService?: AccountBalanceService\n pendingTransactionsArchivist?: ReadArchivist\n pendingTransactionsService?: PendingTransactionsService\n rejectedTransactionsArchivist?: ArchivistInstance\n rewardAddress?: Address\n stakeIntentService?: StakeIntentService\n}\n\n@creatableService()\nexport class XyoBlockProducer extends BaseService<XyoBlockProducerParams> implements BlockProducer {\n protected _blockRewardDiviner: BlockRewardDiviner | undefined\n\n static get DefaultBlockSize(): number {\n return DEFAULT_BLOCK_SIZE\n }\n\n get address() {\n return this.account.address\n }\n\n protected get account() {\n return assertEx(this.params.account, () => 'account is required')\n }\n\n protected get accountBalanceService() {\n return assertEx(this.params.accountBalanceService, () => 'accountBalanceService is required')\n }\n\n protected get chainFinalizedArchivist() {\n return assertEx(this.params.chainFinalizedArchivist, () => 'chainFinalizedArchivist is required')\n }\n\n protected get chainInfo() {\n return assertEx(this.params.chainInformation, () => 'chainInfo is required')\n }\n\n protected get electionService() {\n return assertEx(this.params.electionService, () => 'electionService is required')\n }\n\n protected get pendingTransactions() {\n return assertEx(this.params.pendingTransactions, () => 'pendingTransactions is required')\n }\n\n protected get pendingTransactionsService() {\n return assertEx(this.params.pendingTransactionsService, () => 'Missing pendingTransactionsService')\n }\n\n protected get rejectedTransactionsArchivist() {\n return assertEx(this.params.rejectedTransactionsArchivist, () => 'No rejected transactions archivist')\n }\n\n protected get rewardAddress(): Address {\n return assertEx(this.params.rewardAddress, () => 'No reward address provided')\n }\n\n protected get rewardService() {\n return assertEx(this.params.rewardService, () => 'rewardService is required')\n }\n\n protected get stakeIntentService(): StakeIntentService {\n return assertEx(this.params.stakeIntentService, () => 'No StakeIntentService provided')\n }\n\n protected get validateHydratedBlockState() {\n return assertEx(this.params.validateHydratedBlockState, () => 'validateHydratedBlockState is required')\n }\n\n async next(head: WithStorageMeta<BlockBoundWitness>): Promise<HydratedBlock | undefined> {\n // If the block is for another chain, ignore\n if (head.chain !== this.chainInfo.id) return\n const leaders = await this.electionService.getCreatorCommitteeForNextBlock(head)\n // TODO: Should we propose block if creator committee is empty?\n // TODO: Handle the case where we're not the 1st leader but they're not responding\n // at a higher level than here as that's a network issue\n if (leaders?.[0] !== this.address) return\n return this.proposeNextValidBlock(head)\n }\n\n protected async getBlockRewardTransfer(block: number): Promise<Transfer | undefined> {\n if (!this._blockRewardDiviner) {\n // TODO: Adjust to allow for genesis block reward vs. normal block reward\n this._blockRewardDiviner = await FixedPercentageBlockRewardDiviner.create({\n account: 'random',\n blockRewardService: this.rewardService,\n config: {\n rewardAddress: this.rewardAddress,\n rewardPercentageRatio: 50,\n schema: FixedPercentageBlockRewardDivinerConfigSchema,\n },\n })\n }\n const blockHex = assertEx(toHex(block), () => 'Failed to convert block to hex')\n const blockId = new PayloadBuilder<BlockNumber>({ schema: BlockNumberSchema }).fields({ block: blockHex }).build()\n const rewards = await this._blockRewardDiviner.divine([blockId])\n const [reward] = rewards\n return reward\n }\n\n /**\n * Handles the producer redeclaration logic\n * @param head The current head block\n * @returns\n */\n protected async getProducerRedeclaration(head: WithStorageMeta<BlockBoundWitness>): Promise<ChainStakeIntent | undefined> {\n const redeclareIntent = process.env.XYO_PRODUCER_REDECLARE_INTENT\n if (isUndefined(redeclareIntent)) return\n // Decide if we need to redeclare\n const ranges = await this.stakeIntentService.getDeclaredCandidateRanges(this.address, 'producer')\n // TODO: This doesn't handle the case where the producer had declared a range for the future\n // but we're in a range that's not the future\n // Sort in ascending order based on ending range to get range with highest ending block\n const lastRange = ranges.toSorted((a, b) => a[1] > b[1] ? 1 : -1).at(-1)\n if (!lastRange) return\n const [, currentDeclarationEnd] = lastRange\n const currentBlock = head.block\n const timeToProducerExpiration = currentDeclarationEnd - currentBlock\n if (timeToProducerExpiration > XYO_PRODUCER_RESTAKE_WINDOW) return\n // Create redeclaration\n const intent = new PayloadBuilder<ChainStakeIntent>({ schema: ChainStakeIntentSchema }).fields({\n from: this.address,\n intent: 'producer',\n nbf: currentBlock,\n exp: currentBlock + XYO_PRODUCER_RESTAKE_DURATION,\n }).build()\n return intent\n }\n\n protected async proposeNextValidBlock(head: WithStorageMeta<BlockBoundWitness>): Promise<HydratedBlock | undefined> {\n return await this.spanAsync('proposeNextValidBlock', async () => {\n // Calculate the next block components\n const { block: previousBlock } = assertEx(asBlockBoundWitness(head), () => 'Invalid head block')\n const nextBlock = previousBlock + 1\n const nextBlockTransactions = await this.pendingTransactionsService.getPendingTransactions(head._hash, XyoBlockProducer.DefaultBlockSize)\n\n const blockPayloads: AllowedBlockPayload[] = []\n\n // Calculate the optional producer redeclaration and add it if necessary\n const producerRedeclarationPayload = await this.getProducerRedeclaration(head)\n if (producerRedeclarationPayload) blockPayloads.push(producerRedeclarationPayload)\n\n // If there are no transactions and no payloads, we don't need to create a block\n if (blockPayloads.length === 0 && nextBlockTransactions.length === 0) return\n\n // Calculate the optional block reward transfer and add if necessary\n const rewardTransferPayload = await this.getBlockRewardTransfer(nextBlock)\n if (rewardTransferPayload) blockPayloads.push(rewardTransferPayload)\n\n const transactionTransfers = await generateTransactionTransfers(this.address, nextBlockTransactions)\n\n const fundedTransfers: Transfer[] = []\n\n const fundedNextBlockTransactions = nextBlockTransactions.map((tx) => {\n const transfer: Transfer | undefined = transactionTransfers.find(txTransfer => txTransfer.from === tx[0].from)\n if (!transfer) return\n const totalTransferCost = Object.values(transfer?.transfers).reduce((acc, t) => acc + hexToBigInt(t), 0n)\n if (hexToBigInt(this.accountBalanceService.getBalance(this.address)) >= totalTransferCost) {\n fundedTransfers.push(transfer)\n return tx\n }\n }).filter(exists)\n\n blockPayloads.push(...fundedTransfers)\n\n // Build the block\n const block = await buildBlock(head, fundedNextBlockTransactions, blockPayloads, [this.account])\n console.log('buildBlock', block)\n const errors = await this.validateHydratedBlockState(block, this.chainInfo.id, this.chainFinalizedArchivist)\n if (errors.length > 0) {\n this.logger?.error('Validation of produced block failed', errors)\n const rejectedTransactions = block[1]\n await this.rejectedTransactionsArchivist.insert(rejectedTransactions)\n } else {\n return block\n }\n })\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { type Address, hexFromBigInt } from '@xylabs/hex'\nimport { XYO_ZERO_ADDRESS } from '@xyo-network/chain-utils'\nimport { HydratedTransactionWrapper } from '@xyo-network/chain-wrappers'\nimport type {\n HydratedTransaction,\n Transfer,\n} from '@xyo-network/xl1-protocol'\nimport {\n MicroXL1,\n mXL1ToXL1, TransferSchema,\n XL1,\n} from '@xyo-network/xl1-protocol'\nimport { transactionRequiredGas } from '@xyo-network/xl1-protocol-sdk'\n\nexport async function generateTransactionTransfers(address: Address, transactions: HydratedTransaction[]): Promise<Transfer[]> {\n const txs = await Promise.all(transactions.map(tx => HydratedTransactionWrapper.parse(tx)))\n\n // merge transactions with the same from address\n const txBaseFeeCosts: Record<Address, XL1> = {}\n for (const tx of txs) {\n txBaseFeeCosts[tx.boundWitness.from] = XL1((txBaseFeeCosts[tx.boundWitness.from] ?? 0n) + mXL1ToXL1(tx.fees.base))\n }\n\n const txGasCosts: Record<Address, XL1> = {}\n for (const tx of txs) {\n const requiredGas = transactionRequiredGas(tx.data)\n const totalGasCostInMicroXL1 = MicroXL1(requiredGas * tx.fees.gasPrice)\n txGasCosts[tx.boundWitness.from] = XL1((txBaseFeeCosts[tx.boundWitness.from] ?? 0n) + mXL1ToXL1(totalGasCostInMicroXL1))\n }\n\n // generate actual Transfer Payloads & burn the base fee\n const payloads = (Object.entries(txBaseFeeCosts) as [Address, XL1][]).map(([from, amount]) => {\n const payload: Transfer = {\n schema: TransferSchema,\n epoch: Date.now(),\n from,\n transfers: {\n // burn the base fee\n [XYO_ZERO_ADDRESS]: hexFromBigInt(amount),\n },\n }\n return payload\n })\n\n // transfer gas cost to producer\n for (const [from, amount] of Object.entries(txGasCosts)) {\n // every gas from should also be a base fee from\n const fromPayload = assertEx(payloads.find(p => p.from === from), () => 'from payload not found')\n fromPayload.transfers[address] = hexFromBigInt(amount)\n }\n\n return payloads\n}\n","import { assertEx } from '@xylabs/assert'\nimport { XyoChainRewards__factory as XyoChainRewardsFactory } from '@xyo-network/typechain'\nimport {\n BaseAccountableServiceParams, BlockRewardService, ChainService,\n toEthAddress,\n} from '@xyo-network/xl1-protocol'\nimport { Provider } from 'ethers/providers'\n\nimport { BaseService, creatableService } from '../BaseService.ts'\n\nexport interface EvmBlockRewardServiceParams extends BaseAccountableServiceParams {\n chainService?: ChainService\n provider?: Provider\n}\n\n@creatableService<EvmBlockRewardService>()\nexport class EvmBlockRewardService extends BaseService<EvmBlockRewardServiceParams> implements BlockRewardService {\n protected _contractAddress: string | undefined\n\n protected get chainService() {\n return assertEx(this.params.chainService, () => 'chainService is required')\n }\n\n protected get contractAddress() {\n return assertEx(this._contractAddress, () => 'contractAddress is required')\n }\n\n protected get provider() {\n return assertEx(this.params.provider, () => 'provider is required')\n }\n\n override async createHandler() {\n await super.createHandler()\n this._contractAddress = await this.chainService.rewardsContract()\n }\n\n async getRewardForBlock(blockNumber: bigint): Promise<bigint> {\n const contract = XyoChainRewardsFactory.connect(toEthAddress(this.contractAddress), this.provider)\n return await contract.calcBlockReward(blockNumber)\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { toFixedPoint } from '@xylabs/decimal-precision'\nimport { Promisable } from '@xylabs/promise'\nimport { rewardFromBlockNumber } from '@xyo-network/chain-protocol'\nimport { BaseServiceParams, BlockRewardService } from '@xyo-network/xl1-protocol'\n\nimport { BaseService, creatableService } from '../BaseService.ts'\n\nexport interface XyoBlockRewardServiceParams extends BaseServiceParams {\n creatorReward?: bigint\n initialStepReward?: bigint\n minRewardPerBlock?: bigint\n stepFactorDenominator?: bigint\n stepFactorNumerator?: bigint\n stepSize?: bigint\n}\n\n@creatableService()\nexport class XyoBlockRewardService extends BaseService<XyoBlockRewardServiceParams> implements BlockRewardService {\n protected readonly rewardFromBlockNumber = rewardFromBlockNumber(18)\n\n constructor(\n {\n creatorReward = toFixedPoint(20_000_000_000n),\n initialStepReward = toFixedPoint(3000n),\n minRewardPerBlock = toFixedPoint(30n),\n stepFactorDenominator = 100n,\n stepFactorNumerator = 90n,\n stepSize = 1_000_000n,\n }: Partial<XyoBlockRewardServiceParams> = {},\n ) {\n super({\n initialStepReward, minRewardPerBlock, stepSize, stepFactorDenominator, stepFactorNumerator, creatorReward,\n })\n }\n\n get creatorReward() {\n return assertEx(this.params.creatorReward, () => 'creatorReward is required')\n }\n\n get initialReward() {\n return assertEx(this.params.initialStepReward, () => 'initialStepReward is required')\n }\n\n get minRewardPerBlock() {\n return assertEx(this.params.minRewardPerBlock, () => 'minRewardPerBlock is required')\n }\n\n get stepFactorDenominator() {\n return assertEx(this.params.stepFactorDenominator, () => 'stepFactorDenominator is required')\n }\n\n get stepFactorNumerator() {\n return assertEx(this.params.stepFactorNumerator, () => 'stepFactorNumerator is required')\n }\n\n get stepSize() {\n return assertEx(this.params.stepSize, () => 'stepSize is required')\n }\n\n getRewardForBlock(blockNumber: bigint): Promisable<bigint> {\n return this.rewardFromBlockNumber(\n blockNumber,\n this.initialReward,\n this.stepSize,\n this.stepFactorNumerator,\n this.stepFactorDenominator,\n this.minRewardPerBlock,\n this.creatorReward,\n )\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Promisable } from '@xylabs/promise'\nimport { AccountInstance } from '@xyo-network/account-model'\nimport { ArchivistInstance, ReadArchivist } from '@xyo-network/archivist-model'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport {\n BaseServiceParams,\n BlockBoundWitness,\n BlockRewardService,\n ChainInformation,\n ElectionService,\n HydratedBlockStateValidationFunction,\n HydratedTransaction,\n HydratedTransactionWithStorageMeta,\n StakeIntentService,\n} from '@xyo-network/xl1-protocol'\n\nimport { BaseService, creatableService } from '../BaseService.ts'\nimport { Validator } from './model/index.ts'\n\nconst addStorageMeta = async ([tx, payloads]: HydratedTransaction): Promise<HydratedTransactionWithStorageMeta> => {\n return [await PayloadBuilder.addStorageMeta(tx), await PayloadBuilder.addStorageMeta(payloads)]\n}\n\nexport interface XyoValidatorParams extends BaseServiceParams {\n account?: AccountInstance\n chainFinalizedArchivist?: ReadArchivist\n chainInformation?: ChainInformation\n electionService?: ElectionService\n pendingTransactions?: ArchivistInstance\n rewardService?: BlockRewardService\n stakeIntentService?: StakeIntentService\n validateHydratedBlockState?: HydratedBlockStateValidationFunction\n}\n\n@creatableService()\nexport class XyoValidator<TParams extends XyoValidatorParams = XyoValidatorParams> extends BaseService<TParams> implements Validator {\n get address() {\n return this.account.address\n }\n\n protected get account() {\n return assertEx(this.params.account, () => 'account is required')\n }\n\n protected get chainFinalizedArchivist() {\n return assertEx(this.params.chainFinalizedArchivist, () => 'chainFinalizedArchivist is required')\n }\n\n protected get chainInfo() {\n return assertEx(this.params.chainInformation, () => 'chainInfo is required')\n }\n\n protected get electionService() {\n return assertEx(this.params.electionService, () => 'electionService is required')\n }\n\n protected get pendingTransactions() {\n return assertEx(this.params.pendingTransactions, () => 'pendingTransactions is required')\n }\n\n protected get rewardService() {\n return assertEx(this.params.rewardService, () => 'rewardService is required')\n }\n\n validatePendingBlock(_block: BlockBoundWitness): Promisable<Error[]> {\n return [] // await validateBlockProtocol(block, this.chainInfo)\n }\n\n // TODO: Move to validator and inherit this class from validator\n async validatePendingTransaction(hydratedTransaction: HydratedTransaction): Promise<boolean> {\n const [tx] = await addStorageMeta(hydratedTransaction)\n // Ensure not confirmed already (replay attack)\n if ((await this.chainFinalizedArchivist.get([tx._hash])).length > 0) return false\n // TODO: Ensure transaction is valid (double spend, has voucher, has required stake, etc.)\n // TODO: Ensure validator stake is valid\n return await Promise.resolve(true)\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Address, Hash } from '@xylabs/hex'\nimport { hexToLast4BytesInt, shuffleWithSeed } from '@xyo-network/chain-utils'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport type {\n BaseServiceParams, ChainBlockNumberIterator, ChainStakeViewer, StakeIntentService,\n} from '@xyo-network/xl1-protocol'\nimport { BlockBoundWitness, ElectionService } from '@xyo-network/xl1-protocol'\n\nimport { BaseService, creatableService } from '../BaseService.ts'\n\nexport interface XyoElectionServicesParams extends BaseServiceParams {\n chainIterator?: ChainBlockNumberIterator\n chainStakeViewer?: ChainStakeViewer\n stakeIntentService?: StakeIntentService\n}\n\n@creatableService()\nexport class XyoElectionService extends BaseService<XyoElectionServicesParams> implements ElectionService {\n constructor(params: XyoElectionServicesParams) {\n super(params)\n }\n\n get chainIterator() {\n return assertEx(this.params.chainIterator, () => 'No chain iterator')\n }\n\n get chainStakeViewer() {\n return assertEx(this.params.chainStakeViewer, () => 'No chain stake viewer')\n }\n\n get stakeIntentService() {\n return assertEx(this.params.stakeIntentService, () => 'No staked intent service')\n }\n\n async getCreatorCommitteeForNextBlock(current: BlockBoundWitness): Promise<Address[]> {\n return await this.spanAsync('getCreatorCommitteeForNextBlock', async () => {\n const nextBlock = current.block + 1\n const candidates = await this.stakeIntentService.getDeclaredCandidatesForBlock(nextBlock, 'producer')\n const previousBlockHash = await PayloadBuilder.hash(current)\n return this.generateCreatorCommittee(candidates, previousBlockHash)\n })\n }\n\n protected generateCreatorCommittee(candidates: Address[], previousBlockHash: Hash, maxSize = 3): Address[] {\n const creators = new Set<Address>(candidates)\n const seed = hexToLast4BytesInt(previousBlockHash)\n const creatorArray = shuffleWithSeed(creators, seed)\n return creatorArray.slice(0, maxSize)\n }\n}\n","import { ValueType } from '@opentelemetry/api'\nimport { filterAs, filterAsync } from '@xylabs/array'\nimport { assertEx } from '@xylabs/assert'\nimport { exists } from '@xylabs/exists'\nimport { forget } from '@xylabs/forget'\nimport { Hash } from '@xylabs/hex'\nimport { MemoryArchivist } from '@xyo-network/archivist-memory'\nimport { ArchivistInstance } from '@xyo-network/archivist-model'\nimport { validateTransaction } from '@xyo-network/chain-validation'\nimport {\n Payload, Sequence, WithStorageMeta,\n} from '@xyo-network/payload-model'\nimport {\n asOptionalTransactionBoundWitnessWithStorageMeta, BaseServiceParams, ChainIdentification, HydratedTransactionWithStorageMeta,\n PendingTransactionsService, TransactionBoundWitness,\n} from '@xyo-network/xl1-protocol'\nimport { flattenHydratedTransactions, tryHydrateTransaction } from '@xyo-network/xl1-protocol-sdk'\nimport { Mutex } from 'async-mutex'\n\nimport { BaseService, creatableService } from '../BaseService.ts'\n\nexport interface XyoPendingTransactionsServiceParams extends BaseServiceParams {\n chainArchivist?: ArchivistInstance\n chainIdentification?: ChainIdentification\n pendingTransactionsArchivist?: ArchivistInstance\n rejectedTransactionsArchivist?: ArchivistInstance\n}\n\n@creatableService()\nexport class XyoPendingTransactionsService extends BaseService<XyoPendingTransactionsServiceParams> implements PendingTransactionsService {\n private static readonly MutexPriority = {\n /**\n * Priority for inserting new transactions\n */\n InsertNewTransactions: 5,\n /**\n * Priority for reading pending transactions\n */\n ReadTransactions: 3,\n /**\n * Priority for removing rejected transactions\n */\n RemoveRejectedTransactions: 2,\n /**\n * Priority for removing finalized transactions\n */\n RemoveFinalizedTransactions: 1,\n } as const\n\n /**\n * A mutex to ensure that the counting the number of pending transactions is\n * not called concurrently\n */\n private _countPendingTransactionsMutex = new Mutex()\n\n /**\n * A local Archivist optimized for fast retrieval that stores only validated\n * pending transactions\n */\n private _curatedPendingTransactionsArchivist: MemoryArchivist | undefined\n\n /**\n * The last count of total pending transactions\n */\n private _pendingTransactionsCount: number = 0\n\n /**\n * A mutex to ensure that the curated pending transactions archivist is\n * updated in a thread-safe manner\n */\n private _updateCuratedPendingTransactionsArchivistMutex = new Mutex()\n\n private get chainArchivist() {\n return assertEx(this.params.chainArchivist, () => 'No completed blocks with data archivist')\n }\n\n private get chainIdentification() {\n return assertEx(this.params.chainIdentification, () => 'No chain id')\n }\n\n private get pendingTransactionsArchivist() {\n return assertEx(this.params.pendingTransactionsArchivist, () => 'No pending transactions archivist')\n }\n\n private get pendingTransactionsCount() {\n forget(this.countPendingTransactions())\n return this._pendingTransactionsCount\n }\n\n private get pendingTransactionsLocalArchivist() {\n return assertEx(this._curatedPendingTransactionsArchivist, () => 'No pending transactions curated archivist')\n }\n\n private get rejectedTransactionsArchivist() {\n return assertEx(this.params.rejectedTransactionsArchivist, () => 'No rejected transactions archivist')\n }\n\n override async createHandler() {\n await super.createHandler()\n this._curatedPendingTransactionsArchivist = await MemoryArchivist.create({ account: 'random' })\n\n // On new pending transactions, insert them into the curated archivist\n this.pendingTransactionsArchivist.on('inserted', async ({ payloads }) => {\n await this.insertNewTransactions(payloads)\n })\n\n // On new finalized blocks, remove the transactions from the curated archivist\n this.chainArchivist.on('inserted', async ({ payloads }) => {\n await this.removeFinalizedTransactions(payloads)\n })\n\n // On new rejected blocks, remove the transactions from the curated archivist\n this.rejectedTransactionsArchivist.on('inserted', async ({ payloads }) => {\n await this.removeRejectedTransactions(payloads)\n })\n\n const pendingTransactionsGauge = this.meter?.createObservableGauge(\n 'xyo_pending_transactions_count',\n { description: 'The current number of pending transactions', valueType: ValueType.INT },\n )\n pendingTransactionsGauge?.addCallback((observer) => {\n observer.observe(this.pendingTransactionsCount)\n })\n }\n\n async getPendingTransactions(head: Hash, limit: number): Promise<HydratedTransactionWithStorageMeta[]> {\n return await this.spanAsync('getPendingTransactions', async () => {\n return await this._updateCuratedPendingTransactionsArchivistMutex.runExclusive(async () => {\n const foundPendingTransactions: WithStorageMeta<TransactionBoundWitness>[] = []\n let cursor: Sequence | undefined\n while (foundPendingTransactions.length < limit) {\n const payloads = await this.pendingTransactionsLocalArchivist.next({\n limit: 100, order: 'asc', cursor,\n })\n if (payloads.length === 0) break\n cursor = payloads.at(-1)?._sequence\n const transactions = payloads.map(payload => asOptionalTransactionBoundWitnessWithStorageMeta(payload)).filter(exists)\n foundPendingTransactions.push(...transactions)\n }\n const hydratedTransactions = await Promise.all(\n foundPendingTransactions.map(tx => tryHydrateTransaction(this.pendingTransactionsLocalArchivist, tx._hash)),\n )\n return hydratedTransactions.filter(exists)\n }, XyoPendingTransactionsService.MutexPriority.ReadTransactions)\n })\n }\n\n private async countPendingTransactions() {\n if (this._countPendingTransactionsMutex.isLocked()) return\n await this._countPendingTransactionsMutex.runExclusive(async () => {\n const payloads = (await this._curatedPendingTransactionsArchivist?.all()) ?? []\n const pendingTransactions = filterAs(payloads, asOptionalTransactionBoundWitnessWithStorageMeta)\n this._pendingTransactionsCount = pendingTransactions.length\n })\n }\n\n private async filterAlreadyFinalizedTransactions(payloads: WithStorageMeta<Payload>[]): Promise<WithStorageMeta<TransactionBoundWitness>[]> {\n const incomingTransactions = filterAs(payloads, asOptionalTransactionBoundWitnessWithStorageMeta)\n const incomingTransactionHashes = incomingTransactions.map(payload => payload._hash)\n const finalizedTransactions = await this.chainArchivist.get(incomingTransactionHashes)\n const finalizedTransactionHashes = new Set(finalizedTransactions.map(item => item._hash))\n const nonFinalizedTransactions = incomingTransactions.filter(item => !finalizedTransactionHashes.has(item._hash))\n return nonFinalizedTransactions\n }\n\n private async insertNewTransactions(payloads: WithStorageMeta<Payload>[]) {\n return await this.spanAsync('InsertNewTransactions', async () => {\n return await this._updateCuratedPendingTransactionsArchivistMutex.runExclusive(async () => {\n // Check incoming transactions against finalized transactions\n const unprocessedTransactions = await this.filterAlreadyFinalizedTransactions(payloads)\n // Hydrate all unprocessed transactions\n const hydratedUnprocessedTransactions = (await Promise.all(unprocessedTransactions.map((tx) => {\n return tryHydrateTransaction(this.pendingTransactionsArchivist, tx._hash)\n }))).filter(exists)\n // Filter to only valid transactions\n const validTransactions = await filterAsync(hydratedUnprocessedTransactions, async (tx) => {\n const errors = await validateTransaction(tx, this.chainIdentification.id)\n return errors.length > 0 ? false : true\n })\n await this.pendingTransactionsLocalArchivist.insert(flattenHydratedTransactions(validTransactions))\n }, XyoPendingTransactionsService.MutexPriority.InsertNewTransactions)\n })\n }\n\n private async removeFinalizedTransactions(payloads: WithStorageMeta<Payload>[]) {\n return await this.removeTransactions(payloads, 'RemoveFinalizedTransactions')\n }\n\n private async removeRejectedTransactions(payloads: WithStorageMeta<Payload>[]) {\n return await this.removeTransactions(payloads, 'RemoveRejectedTransactions')\n }\n\n private async removeTransactions(\n payloads: WithStorageMeta<Payload>[],\n priority: keyof typeof XyoPendingTransactionsService.MutexPriority,\n ) {\n return await this.spanAsync(priority, async () => {\n return await this._updateCuratedPendingTransactionsArchivistMutex.runExclusive(async () => {\n const transactions = filterAs(payloads, asOptionalTransactionBoundWitnessWithStorageMeta)\n await this.pendingTransactionsLocalArchivist.delete(transactions.map(tx => tx._hash))\n }, XyoPendingTransactionsService.MutexPriority[priority])\n })\n }\n}\n","import { filterAs } from '@xylabs/array'\nimport { exists } from '@xylabs/exists'\nimport type { Hash } from '@xylabs/hex'\nimport type { ArchivistInstance } from '@xyo-network/archivist-model'\nimport type { BoundWitness } from '@xyo-network/boundwitness-model'\nimport { asOptionalBoundWitness } from '@xyo-network/boundwitness-model'\nimport { payloadSchemasContains } from '@xyo-network/boundwitness-validator'\nimport { BoundWitnessWrapper } from '@xyo-network/boundwitness-wrapper'\nimport type {\n BlockBoundWitness, ChainStakeIntent, Intent,\n} from '@xyo-network/xl1-protocol'\nimport { asOptionalChainStakeIntent, ChainStakeIntentSchema } from '@xyo-network/xl1-protocol'\n\nexport const getBlockSignedStakeDeclarations = async (block: BlockBoundWitness, archivist: ArchivistInstance, intent: Intent): Promise<ChainStakeIntent[]> => {\n // Get payloads in block\n const blockData = await archivist.get(block.payload_hashes)\n // Filter Payloads in block to BoundWitnesses\n const bwsFromBlock = filterAs(blockData, asOptionalBoundWitness)\n // Filter to BoundWitnesses with StakeIntent payloads\n const bwsFromBlockWithDeclarations = bwsFromBlock.filter(bw => payloadSchemasContains(bw, ChainStakeIntentSchema))\n // Filter to only valid signed BWs\n const validBlockBwsWithDeclarations = await filterToValidSignedBoundWitnesses(bwsFromBlockWithDeclarations)\n return (await Promise.all(validBlockBwsWithDeclarations.map(async (bw) => {\n // Get staked intent hashes from signed declarations\n const stakeIntentHashes = validBlockBwsWithDeclarations\n .flatMap(mapBoundWitnessToStakeIntentHashes)\n .filter(exists)\n // Get staked intent payloads\n const payloads = await archivist.get(stakeIntentHashes)\n // Filter payloads to staked intents\n const stakeIntents = filterAs(payloads, asOptionalChainStakeIntent)\n // that are producers\n .filter(p => p.intent === intent)\n // where the issuer of the intent is also the signer of this BW\n .filter(p => bw.addresses.includes(p.from))\n\n return stakeIntents\n }))).flat()\n}\n\nconst filterToValidSignedBoundWitnesses = async (bws: BoundWitness[]): Promise<BoundWitness[]> => {\n const validBwIndexes = await Promise.all(bws.map(bw => BoundWitnessWrapper.parse(bw).getValid()))\n return bws.filter((_, index) => validBwIndexes[index])\n}\n\nconst mapBoundWitnessToStakeIntentHashes = (bw: BoundWitness): (Hash | undefined)[] => {\n return bw.payload_schemas.map((schema, index) => schema === ChainStakeIntentSchema ? bw.payload_hashes[index] : undefined)\n}\n","import { filterAs } from '@xylabs/array'\nimport { assertEx } from '@xylabs/assert'\nimport {\n Address, asAddress, Hash,\n} from '@xylabs/hex'\nimport { ArchivistInstance, ArchivistNextOptions } from '@xyo-network/archivist-model'\nimport {\n analyzeChain, ChainStakeIntentAnalyzer,\n isChainSummaryStakeIntent,\n} from '@xyo-network/chain-analyze'\nimport {\n DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS,\n findFirstMatching, IntervalMap,\n SerializedIntervalMap,\n} from '@xyo-network/chain-utils'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport { Payload, WithStorageMeta } from '@xyo-network/payload-model'\nimport type {\n BaseServiceParams, EventingChainBlockNumberIterator, Intent,\n} from '@xyo-network/xl1-protocol'\nimport {\n asOptionalBlockBoundWitness, asOptionalBlockBoundWitnessWithStorageMeta,\n asOptionalChainIndexingServiceStateWithStorageMeta, asOptionalChainStakeIntent, ChainIndexingServiceState, ChainIndexingServiceStateSchema, ChainStakeViewer,\n isChainIndexingServiceState,\n StakeIntentService,\n} from '@xyo-network/xl1-protocol'\nimport { Mutex } from 'async-mutex'\nimport { LRUCache } from 'lru-cache'\n\nimport { BaseService, creatableService } from '../BaseService.ts'\n\nexport interface XyoStakeIntentServiceParams extends BaseServiceParams {\n chainArchivist?: ArchivistInstance\n chainIterator?: EventingChainBlockNumberIterator\n chainStakeViewer?: ChainStakeViewer\n stakeIntentStateArchivist?: ArchivistInstance\n}\n\n/**\n * The number of blocks to periodically persist state\n */\nconst STATE_PERSISTENCE_INTERVAL = 60n\n\nconst ACTIVE_STAKE_TTL = 1000 * 60 * 60 * 2 // 2 hours in milliseconds\nconst NO_ACTIVE_STAKE_TTL = 1000 * 2 // 2 seconds in milliseconds\nconst STAKE_CACHE_MAX_ENTRIES = 10_000\n\n@creatableService()\nexport class XyoStakeIntentService extends BaseService<XyoStakeIntentServiceParams> implements StakeIntentService {\n // TODO: Use hash instead of block number to handle chain reorgs\n protected _lastIndexedBlockHash: Hash | undefined = undefined\n // TODO: Interval tree per declaration (bank, validator, etc.)\n // NOTE: Ideally move to DataIntervalTree to handle declared\n // ranges as it enables range queries in O(min(n, k * log n)) time,\n // where k is the number of intervals in the output list time\n // Currently using set based because it's simpler, equivalent\n // in performance for small sets, and (most importantly) easily\n // persisted so we can recover state on restart.\n protected _producers: IntervalMap<Address> = new IntervalMap()\n protected _stakeCache = new LRUCache<Address, bigint>({ max: STAKE_CACHE_MAX_ENTRIES })\n protected _updateMutex = new Mutex()\n\n constructor(params: XyoStakeIntentServiceParams) {\n super(params)\n this.chainIterator.on('headUpdated', async () => {\n await this.updateIndex()\n })\n }\n\n protected get chainArchivist() {\n return assertEx(this.params.chainArchivist, () => 'chainArchivist not set')\n }\n\n protected get chainIterator() {\n return assertEx(this.params.chainIterator, () => 'chainIterator not set')\n }\n\n protected get chainStakeViewer() {\n return assertEx(this.params.chainStakeViewer, () => 'chainStakeViewer not set')\n }\n\n protected get stakeIntentStateArchivist() {\n return assertEx(this.params.stakeIntentStateArchivist, () => 'stakeIntentStateArchivist not set')\n }\n\n override async createHandler(): Promise<void> {\n const head = await this.chainIterator.head()\n const headHash = await PayloadBuilder.hash(head)\n if (head?.block === undefined) return\n await this.recoverState(headHash)\n await this.updateIndex(true)\n }\n\n async getDeclaredCandidateRanges(address: Address, intent: Intent): Promise<Readonly<Readonly<[number, number]>[]>> {\n await Promise.resolve()\n assertEx(intent === 'producer', () => `Error: Support not yet added for intent ${intent}`)\n const results = this._producers.get(address)\n return results ?? []\n }\n\n async getDeclaredCandidatesForBlock(block: number, intent: Intent): Promise<Address[]> {\n return await this.spanAsync('getDeclaredCandidatesForBlock', async () => {\n assertEx(intent === 'producer', () => `Error: Support not yet added for intent ${intent}`)\n const results = this._producers.findAllContaining(block)\n const candidates = [...results]\n const validCandidates = await this.filterToValidStake(candidates, this.chainStakeViewer)\n return validCandidates\n })\n }\n\n async isStakedForBlock(block: number, intent: Intent, address: Address): Promise<boolean> {\n const candidates = await this.getDeclaredCandidatesForBlock(block, intent)\n return candidates.includes(address)\n }\n\n private async filterToValidStake(\n candidates: Address[],\n chainStakeViewer: ChainStakeViewer,\n requiredMinimumStake: bigint = 1n,\n ): Promise<Address[]> {\n type CandidateStake = { candidate: Address; stake: bigint }\n\n // Find the stake for each candidate\n const candidatesWithStake: CandidateStake[] = await Promise.all(\n candidates.map(async (candidate) => {\n // Check if the stake is already cached\n const stake = this._stakeCache.get(candidate)\n if (stake === undefined) {\n // Fetch from chainStakeViewer if not cached\n const activeStake = await chainStakeViewer.activeByAddressStaked(`${candidate}`)\n if (activeStake > 0n) {\n // Store result in cache\n this._stakeCache.set(candidate, activeStake, { ttl: ACTIVE_STAKE_TTL })\n } else {\n this._stakeCache.set(candidate, activeStake, { ttl: NO_ACTIVE_STAKE_TTL })\n }\n return { candidate, stake: activeStake }\n } else {\n return { candidate, stake }\n }\n }),\n )\n\n // Filter out candidates whose stake is greater than or equal to the required minimum\n return candidatesWithStake\n .filter(({ stake }) => stake >= requiredMinimumStake)\n .map(({ candidate }) => candidate)\n }\n\n private async persistState(current: Hash): Promise<void> {\n const state = this._producers.serialize()\n const payload = new PayloadBuilder<ChainIndexingServiceState<SerializedIntervalMap>>({ schema: ChainIndexingServiceStateSchema })\n .fields({ endBlockHash: current, state })\n .build()\n await this.stakeIntentStateArchivist.insert([payload])\n }\n\n private async recoverState(current: Hash): Promise<void> {\n const currentBlock = assertEx(asOptionalBlockBoundWitness((await this.chainArchivist.get([current]))?.[0]), () => `Block ${current} not found`)\n const currentBlockNum = currentBlock.block\n // Find last state before current head (in case of rollback, we indexed past it on an uncle chain, etc.)\n const opts: ArchivistNextOptions = { ...DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS }\n while (true) {\n const predicate = (p: WithStorageMeta<Payload>) => {\n const state = asOptionalChainIndexingServiceStateWithStorageMeta(p)\n return state ? true : false\n }\n const state = await findFirstMatching(this.stakeIntentStateArchivist, predicate, opts)\n if (isChainIndexingServiceState<SerializedIntervalMap>(state)) {\n const indexed = (await this.chainArchivist.get([state.endBlockHash]))?.[0]\n const indexedBlock = asOptionalBlockBoundWitnessWithStorageMeta(indexed)\n if (indexedBlock) {\n const indexedBlockNum = indexedBlock.block\n if (indexedBlockNum <= currentBlockNum) {\n const data = state.state as SerializedIntervalMap\n this._producers = new IntervalMap(data)\n this._lastIndexedBlockHash = indexedBlock._hash\n break\n }\n }\n } else {\n // No state found, start from genesis\n break\n }\n opts.open = true\n }\n }\n\n private async updateIndex(displayProgress = false): Promise<void> {\n if (this._updateMutex.isLocked()) {\n return\n }\n await this._updateMutex.runExclusive(async () => {\n return await this.spanAsync('updateIndex', async () => {\n const currentHead = await this.chainIterator.head()\n const currentHeadHash = await PayloadBuilder.hash(currentHead)\n const result = await analyzeChain(this.chainArchivist, [new ChainStakeIntentAnalyzer('producer')], currentHeadHash, this._lastIndexedBlockHash)\n const signedDeclarations = filterAs(result.find(isChainSummaryStakeIntent)?.intents ?? [], asOptionalChainStakeIntent)\n if (currentHead.block === undefined) return\n const currentHeadBlockNum = currentHead.block\n if (displayProgress) this.logger?.info(`Updating index through 0x${currentHeadBlockNum}`)\n for (const signedDeclaration of signedDeclarations) {\n const { exp, nbf } = signedDeclaration\n const start = nbf\n const stop = exp\n const address = asAddress(signedDeclaration?.from)\n if (start !== undefined && stop !== undefined && address !== undefined) {\n this._producers.insert(address, start, stop)\n }\n }\n /*\n if (index % STATE_PERSISTENCE_INTERVAL === 0n) {\n if (displayProgress) this.logger?.info(`Persisting state at block ${index}`)\n await this.persistState(await PayloadBuilder.hash(block))\n }\n */\n this._lastIndexedBlockHash = currentHeadHash\n })\n })\n }\n}\n","import { Base } from '@xylabs/base'\nimport type { Address } from '@xylabs/hex'\nimport { toAddress } from '@xylabs/hex'\nimport type { Promisable } from '@xylabs/promise'\nimport type { StakedXyoChain } from '@xyo-network/typechain'\nimport { StakedXyoChain__factory as StakedXyoChainFactory } from '@xyo-network/typechain'\nimport type { BaseServiceParams, ChainService } from '@xyo-network/xl1-protocol'\nimport { getAddress } from 'ethers/address'\nimport type { ContractRunner } from 'ethers/providers'\n\nexport interface EvmChainServiceParams extends BaseServiceParams {\n contract: StakedXyoChain\n id: Address\n runner: ContractRunner\n}\n\n/**\n * A class that represents a chain stake as backed by an EVM smart contract\n */\nexport class EvmChainService extends Base<EvmChainServiceParams> implements ChainService {\n private _contract: StakedXyoChain\n\n protected constructor(params: EvmChainServiceParams) {\n super(params)\n this._contract = params.contract\n }\n\n get id(): Address {\n return this.params.id\n }\n\n get runner(): ContractRunner {\n return this.params.runner\n }\n\n static create({\n id, runner, logger, traceProvider, meterProvider,\n }: Omit<EvmChainServiceParams, 'contract'>): Promisable<EvmChainService> {\n const contractAddress = getAddress(id)\n const contract: StakedXyoChain = StakedXyoChainFactory.connect(contractAddress, runner)\n return new this({\n id, contract, runner, logger, traceProvider, meterProvider,\n })\n }\n\n async active(): Promise<bigint> {\n return await this._contract.active()\n }\n\n async activeByAddressStaked(address: string): Promise<bigint> {\n return await this._contract.activeByAddressStaked(getAddress(address))\n }\n\n async activeByStaker(address: string): Promise<bigint> {\n return await this._contract.activeByStaker(getAddress(address))\n }\n\n async addStake(staked: string, amount: bigint): Promise<boolean> {\n const result = await this._contract.addStake(getAddress(staked), amount)\n await result.wait()\n return true\n }\n\n async chainId(): Promise<Address> {\n return toAddress(await this._contract.chainId())\n }\n\n async forkedAtBlockNumber(): Promise<bigint> {\n return await this._contract.forkedAtBlockNumber()\n }\n\n async forkedAtHash(): Promise<bigint> {\n return await this._contract.forkedAtHash()\n }\n\n async forkedChainId(): Promise<Address> {\n return toAddress(await this._contract.forkedChainId())\n }\n\n async minWithdrawalBlocks(): Promise<bigint> {\n return await this._contract.minWithdrawalBlocks()\n }\n\n async pending(): Promise<bigint> {\n return await this._contract.pending()\n }\n\n async pendingByStaker(staker: string): Promise<bigint> {\n return await this._contract.pendingByStaker(getAddress(staker))\n }\n\n async removeStake(slot: bigint): Promise<boolean> {\n const result = await this._contract.removeStake(slot)\n await result.wait()\n return true\n }\n\n async rewardsContract(): Promise<string> {\n return await this._contract.rewardsContract()\n }\n\n async stakingTokenAddress(): Promise<string> {\n return await this._contract.stakingTokenAddress()\n }\n\n async withdrawStake(slot: bigint): Promise<boolean> {\n const result = await this._contract.withdrawStake(slot)\n await result.wait()\n return true\n }\n\n async withdrawn(): Promise<bigint> {\n return await this._contract.withdrawn()\n }\n\n async withdrawnByStaker(staker: string): Promise<bigint> {\n return await this._contract.withdrawnByStaker(getAddress(staker))\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport type { BaseParams } from '@xylabs/base'\nimport { BaseEmitter } from '@xylabs/events'\nimport { isDefined, isNull } from '@xylabs/typeof'\nimport type { ArchivistInstance } from '@xyo-network/archivist-model'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport type {\n BlockBoundWitness, ChainIdentification,\n ChainIteratorEventData,\n EventingChainBlockNumberIterator,\n XyoChainIteratorParams,\n} from '@xyo-network/xl1-protocol'\nimport {\n asBlockBoundWitness, asOptionalBlockBoundWitness,\n isBlockBoundWitness,\n} from '@xyo-network/xl1-protocol'\nimport { LRUCache } from 'lru-cache'\n\nexport class XyoChainBlockNumberIterator extends BaseEmitter<BaseParams, ChainIteratorEventData> implements EventingChainBlockNumberIterator {\n protected _blocksByBlockNumber = new LRUCache<number, BlockBoundWitness>({ max: 10_000 })\n protected _chainArchivist: ArchivistInstance\n protected _chainInformation: ChainIdentification\n protected _head: BlockBoundWitness\n\n protected constructor(params: XyoChainIteratorParams) {\n super({})\n const { chainArchivist: archivist, head } = params\n this._chainArchivist = archivist\n this._head = head\n this._chainInformation = { id: head.chain }\n }\n\n get archivist(): ArchivistInstance { return this._chainArchivist }\n\n get chainIdentification(): ChainIdentification { return this._chainInformation }\n\n static async create(params: XyoChainIteratorParams): Promise<XyoChainBlockNumberIterator> {\n await Promise.resolve()\n return new XyoChainBlockNumberIterator(params)\n }\n\n async get(block: number): Promise<BlockBoundWitness> {\n // Bail early if the block requested is newer than the current head\n assertEx(this._head.block >= block, () => `Block requested is newer than the current head [${block}]`)\n const cached = this._blocksByBlockNumber.get(block)\n if (cached) return cached\n // Start at the current head and traverse backwards until the requested block is found\n const startingBlock = this._head\n const currentBlockHash = await PayloadBuilder.hash(startingBlock)\n let currentBlock = (await this._chainArchivist.get([currentBlockHash])).at(0)\n while (isDefined(currentBlock)) {\n assertEx(asBlockBoundWitness(currentBlock), () => `Expected hash to be a block bound witness [${currentBlock?._hash}]`)\n if (isBlockBoundWitness(currentBlock)) {\n this._blocksByBlockNumber.set(currentBlock.block, currentBlock)\n if (currentBlock.block === block) {\n return currentBlock\n }\n const { previous } = currentBlock\n if (isNull(previous)) break\n currentBlock = (await this._chainArchivist.get([previous])).at(0)\n }\n }\n throw new Error(`Block not found: ${block}`)\n }\n\n async head(): Promise<BlockBoundWitness> {\n return await Promise.resolve(this._head)\n }\n\n async next(block: number): Promise<BlockBoundWitness | undefined> {\n const currentBlock = block\n const nextBlockNumber = currentBlock + 1\n return await this.get(nextBlockNumber)\n }\n\n // TODO: Decide on inclusive/exclusive (probably need inclusive to account for chain head)\n // and then communicate via method name and documentation\n async previous(block: number | undefined = undefined, count: number = 1): Promise<BlockBoundWitness[]> {\n const results: BlockBoundWitness[] = []\n let currentBlock: BlockBoundWitness | undefined = isDefined(block) ? (await this.get(block)) : this._head\n while (currentBlock && results.length < count) {\n if (isBlockBoundWitness(currentBlock)) {\n results.push(currentBlock)\n const { previous } = currentBlock\n if (isNull(previous)) break\n const nextBlock = await this._chainArchivist.get([previous])\n currentBlock = asOptionalBlockBoundWitness(nextBlock[0])\n } else {\n const hash = PayloadBuilder.hash(currentBlock)\n assertEx(asBlockBoundWitness(currentBlock), () => `Expected hash to be a block bound witness [${hash}]`)\n }\n }\n return results\n }\n\n async updateHead(head: BlockBoundWitness): Promise<void> {\n // Async to allow for re-indexing, etc.\n await Promise.resolve()\n this._head = head\n void this.emit('headUpdated', { blocks: [head] })\n }\n}\n"],"mappings":";;;;AAAA,SAASA,gBAAgB;AACzB,SAEEC,aACK;AACP,SACEC,cAAcC,iBAAiBC,8BAC1B;AACP,SAAuBC,wBAAwB;;;ACR/C,SAASC,mBAAmB;AAE5B,SAASC,MAAMC,iBAAiB;AAIhC,SAASC,aAAa;AAMf,IAAMC,cAAN,cAAiFC,YAAAA;EAZxF,OAYwFA;;;EACtF,OAAeC,qBAAqB,IAAIC,MAAAA;EAExC,WAAWC,aAAa;AACtB,WAAOC,WAAW,sBAAA,MAA4BA,WAAW,sBAAA,IAA0B,CAAC;EACtF;EAEA,IAAIC,OAAO;AACT,WAAO,KAAKC,YAAYD;EAC1B;EAEA,aAAaE,OAEXC,QACmB;AACnB,UAAMC,SAAS,IAAI,KAAKD,MAAAA;AACxB,QAAIC,OAAOJ,SAAS,cAAe,OAAM,IAAIK,MAAM,2BAAA;AACnD,UAAMD,OAAOE,cAAa;AAC1B,WAAOF;EACT;EAEA,OAAOG,cAAwFJ,QAAiB;AAC9G,QAAI,KAAKL,WAAW,KAAKE,IAAI,EAAG,OAAM,IAAIK,MAAM,qCAAqC,KAAKL,IAAI,EAAE;AAChG,WAAO,KAAKJ,mBAAmBY,aAAa,YAAA;AAC1C,aAAO,MAAM,KAAKN,OAAOC,MAAAA;IAC3B,CAAA;EACF;EAEAG,gBAAkC;AAChC;EACF;EAEAG,KAAQT,MAAcU,IAAgB;AACpC,WAAOD,KAAKT,MAAMU,IAAI,KAAKC,MAAM;EACnC;EAEA,MAAMC,UAAaZ,MAAcU,IAAkC;AACjE,WAAO,MAAME,UAAUZ,MAAMU,IAAI,KAAKC,MAAM;EAC9C;AACF;AAEO,IAAeE,yBAAf,cAEGnB,YAAAA;EAvDV,OAuDUA;;;AAEV;AAOO,SAASoB,mBAAAA;AACd,SAAO,CAAgCb,gBAAAA;AAErCA;EACF;AACF;AALgBa;;;;;;;;;;AD7CT,IAAMC,gCAAN,cAA4CC,YAAAA;SAAAA;;;EACzCC,YAA2C,CAAC;EAC5CC,gBAA6B;EAErC,IAAcC,iBAAiB;AAC7B,WAAOC,SAAS,KAAKC,OAAOF,gBAAgB,MAAM,4BAAA;EACpD;EAEAG,WAAWC,SAAuB;AAChC,WAAOC,iBAAiB,KAAKP,UAAUM,OAAAA,KAAY;MAAEE,UAAUC,MAAM,EAAE;IAAE,CAAA,EAAGD;EAC9E;EAEAE,cAAoC;AAClC,UAAMC,SAA+B,CAAC;AACtC,UAAMC,UAAUC,OAAOD,QAAQ,KAAKZ,SAAS;AAC7C,eAAW,CAACM,SAASQ,OAAAA,KAAYF,SAAS;AACxCD,aAAOL,OAAAA,IAAWC,iBAAiBO,OAAAA,EAASN;IAC9C;AACA,WAAOG;EACT;EAEA,MAAMI,KAAKC,MAA2B;AACpC,UAAMC,WAAW,MAAMC,aACrB,KAAKhB,gBACL;MAAC,IAAIiB,gBAAAA;OACLH,MACA,KAAKf,eACL,CAAC,IACD,KAAKmB,MAAM;AAEb,SAAKpB,YAAYG,SAASc,SAASI,KAAKC,sBAAAA,GAAyBC,UAAU,MAAM,yBAAA;EACnF;AACF;;;;;;AE7BO,IAAMC,kBAAN,MAAMA;EAAb,OAAaA;;;EACXC,eAA0B;AACxB,UAAM,IAAIC,MAAM,yBAAA;EAClB;EAEAC,kBAAwB;AACtB,UAAM,IAAID,MAAM,yBAAA;EAClB;EAEAE,SAASC,cAAkCC,cAAgD;AACzF,UAAM,IAAIJ,MAAM,yBAAA;EAClB;EAEAK,uBAAuBC,cAA8B;AACnD,UAAM,IAAIN,MAAM,yBAAA;EAClB;EAEAO,eAAwB;AACtB,UAAM,IAAIP,MAAM,yBAAA;EAClB;EAEAQ,eAAeC,OAA+B;AAC5C,UAAM,IAAIT,MAAM,yBAAA;EAClB;EAEAU,mBAAmBD,OAA+B;AAChD,UAAM,IAAIT,MAAM,yBAAA;EAClB;EAEAW,oBAAoBF,OAAiC;AACnD,UAAM,IAAIT,MAAM,yBAAA;EAClB;EAEAY,gBAAgBT,cAAiDC,cAAsC;AACrG,UAAM,IAAIJ,MAAM,yBAAA;EAClB;EAEAa,eAAeC,aAAmBC,cAAgCC,oBAAmD;AACnH,UAAM,IAAIhB,MAAM,yBAAA;EAClB;EAEAiB,eAAqB;AACnB,UAAM,IAAIjB,MAAM,yBAAA;EAClB;EAEAkB,eAAeC,UAAmBf,cAAsC;AACtE,UAAM,IAAIJ,MAAM,yBAAA;EAClB;EAEAoB,mBAAmBC,YAA8BC,WAA8B;AAC7E,UAAM,IAAItB,MAAM,yBAAA;EAClB;EAEAuB,qBAAqBnB,cAAgCkB,WAA8B;AACjF,UAAM,IAAItB,MAAM,yBAAA;EAClB;EAEAwB,mCAAmCH,YAAoC;AACrE,UAAM,IAAIrB,MAAM,yBAAA;EAClB;EAEAyB,qCAAqCrB,cAAsC;AACzE,UAAM,IAAIJ,MAAM,yBAAA;EAClB;EAEA0B,YAAYP,UAAmBf,cAAgD;AAC7E,UAAM,IAAIJ,MAAM,yBAAA;EAClB;EAEA2B,mBAA6B;AAC3B,UAAM,IAAI3B,MAAM,yBAAA;EAClB;EAEA4B,qBAAqBC,mBAA2C;AAC9D,UAAM,IAAI7B,MAAM,yBAAA;EAClB;EAEA8B,kBAAkBD,mBAA2C;AAC3D,UAAM,IAAI7B,MAAM,yBAAA;EAClB;EAEA+B,YAAYC,SAAmC;AAC7C,UAAM,IAAIhC,MAAM,yBAAA;EAClB;EAEAiC,iBAAiBd,UAAmBe,cAAuB9B,cAAgD;AACzG,UAAM,IAAIJ,MAAM,yBAAA;EAClB;EAEAmC,sCAAsCd,YAA8Be,mBAAyD;AAC3H,UAAM,IAAIpC,MAAM,yBAAA;EAClB;EAEAqC,wCAAwCjC,cAAgCgC,mBAAyD;AAC/H,UAAM,IAAIpC,MAAM,yBAAA;EAClB;EAEAsC,yBAAyBC,kBAAoE;AAC3F,UAAM,IAAIvC,MAAM,yBAAA;EAClB;EAEAwC,wBAAwBrB,UAAmBf,cAAsC;AAC/E,UAAM,IAAIJ,MAAM,yBAAA;EAClB;EAEAyC,0BAA0BF,kBAAuE;AAC/F,UAAM,IAAIvC,MAAM,yBAAA;EAClB;EAEA0C,gCAAgCrB,YAA8BsB,aAA6B;AACzF,UAAM,IAAI3C,MAAM,yBAAA;EAClB;EAEA4C,kCAAkCxC,cAAgCuC,aAA6B;AAC7F,UAAM,IAAI3C,MAAM,yBAAA;EAClB;EAEA6C,6BAA6BxB,YAAoC;AAC/D,UAAM,IAAIrB,MAAM,yBAAA;EAClB;EAEA8C,+BAA+B1C,cAAsC;AACnE,UAAM,IAAIJ,MAAM,yBAAA;EAClB;EAEA+C,cAAsE;AACpE,UAAM,IAAI/C,MAAM,yBAAA;EAClB;EAEAgD,eAAqB;AACnB,UAAM,IAAIhD,MAAM,yBAAA;EAClB;EAEAiD,2BAAiC;AAC/B,UAAM,IAAIjD,MAAM,yBAAA;EAClB;EAEAkD,aAAsB;AACpB,UAAM,IAAIlD,MAAM,yBAAA;EAClB;EAEAmD,qBAA2B;AACzB,UAAM,IAAInD,MAAM,yBAAA;EAClB;EAEAoD,cAAcpB,SAAuB;AACnC,UAAM,IAAIhC,MAAM,yBAAA;EAClB;EAEAqD,kCAAwC;AACtC,UAAM,IAAIrD,MAAM,yBAAA;EAClB;EAEAsD,sBAA8B;AAC5B,UAAM,IAAItD,MAAM,yBAAA;EAClB;EAEAuD,uBAAuBpD,cAAgD;AACrE,UAAM,IAAIH,MAAM,yBAAA;EAClB;EAEAwD,oBAAoBrD,cAA8F;AAChH,UAAM,IAAIH,MAAM,yBAAA;EAClB;EAEAyD,SAAStC,UAAmBuC,UAA6C;AACvE,UAAM,IAAI1D,MAAM,yBAAA;EAClB;EAEA2D,oBAAoBxD,cAAuH;AACzI,UAAM,IAAIH,MAAM,yBAAA;EAClB;EAEA4D,mBAAmBC,WAA6BC,KAAgC;AAC9E,UAAM,IAAI9D,MAAM,yBAAA;EAClB;EAEA+D,eAAeC,QAAyBC,OAAyBC,SAAoC;AACnG,UAAM,IAAIlE,MAAM,yBAAA;EAClB;EAEAmE,iBAAiBC,SAAuI;AACtJ,UAAM,IAAIpE,MAAM,yBAAA;EAClB;EAEAqE,cAAgC;AAC9B,UAAM,IAAIrE,MAAM,yBAAA;EAClB;EAEAsE,oBAAoBzC,mBAAkC;AACpD,UAAM,IAAI7B,MAAM,yBAAA;EAClB;EAEAuE,gBAAgBC,iBAAuC;AACrD,UAAM,IAAIxE,MAAM,yBAAA;EAClB;AACF;;;AC1NA,SAASyE,YAAAA,iBAAgB;AACzB,SAASC,cAAc;AACvB,SACWC,aAAaC,SAAAA,cACjB;AACP,SAASC,mBAAmB;AAE5B,SACsBC,mCAAmCC,qDAClD;AACP,SAASC,kBAAkB;AAC3B,SAASC,sBAAsB;AAE/B,SAEuBC,qBAAqDC,mBAAoDC,8BAEzH;;;ACjBP,SAASC,YAAAA,iBAAgB;AACzB,SAAuBC,qBAAqB;AAC5C,SAASC,wBAAwB;AACjC,SAASC,kCAAkC;AAK3C,SACEC,UACAC,WAAWC,gBACXC,WACK;AACP,SAASC,8BAA8B;AAEvC,eAAsBC,6BAA6BC,SAAkBC,cAAmC;AACtG,QAAMC,MAAM,MAAMC,QAAQC,IAAIH,aAAaI,IAAIC,CAAAA,OAAMC,2BAA2BC,MAAMF,EAAAA,CAAAA,CAAAA;AAGtF,QAAMG,iBAAuC,CAAC;AAC9C,aAAWH,MAAMJ,KAAK;AACpBO,mBAAeH,GAAGI,aAAaC,IAAI,IAAIC,KAAKH,eAAeH,GAAGI,aAAaC,IAAI,KAAK,MAAME,UAAUP,GAAGQ,KAAKC,IAAI,CAAA;EAClH;AAEA,QAAMC,aAAmC,CAAC;AAC1C,aAAWV,MAAMJ,KAAK;AACpB,UAAMe,cAAcC,uBAAuBZ,GAAGa,IAAI;AAClD,UAAMC,yBAAyBC,SAASJ,cAAcX,GAAGQ,KAAKQ,QAAQ;AACtEN,eAAWV,GAAGI,aAAaC,IAAI,IAAIC,KAAKH,eAAeH,GAAGI,aAAaC,IAAI,KAAK,MAAME,UAAUO,sBAAAA,CAAAA;EAClG;AAGA,QAAMG,WAAYC,OAAOC,QAAQhB,cAAAA,EAAqCJ,IAAI,CAAC,CAACM,MAAMe,MAAAA,MAAO;AACvF,UAAMC,UAAoB;MACxBC,QAAQC;MACRC,OAAOC,KAAKC,IAAG;MACfrB;MACAsB,WAAW;;QAET,CAACC,gBAAAA,GAAmBC,cAAcT,MAAAA;MACpC;IACF;AACA,WAAOC;EACT,CAAA;AAGA,aAAW,CAAChB,MAAMe,MAAAA,KAAWF,OAAOC,QAAQT,UAAAA,GAAa;AAEvD,UAAMoB,cAAcC,UAASd,SAASe,KAAKC,CAAAA,MAAKA,EAAE5B,SAASA,IAAAA,GAAO,MAAM,wBAAA;AACxEyB,gBAAYH,UAAUjC,OAAAA,IAAWmC,cAAcT,MAAAA;EACjD;AAEA,SAAOH;AACT;AAtCsBxB;;;;;;;;;;ADWf,IAAMyC,qBAAqB;AAK3B,IAAMC,gCAAgC;AAMtC,IAAMC,8BAA8B;AAYpC,IAAMC,mBAAN,MAAMA,0BAAyBC,YAAAA;SAAAA;;;EAC1BC;EAEV,WAAWC,mBAA2B;AACpC,WAAON;EACT;EAEA,IAAIO,UAAU;AACZ,WAAO,KAAKC,QAAQD;EACtB;EAEA,IAAcC,UAAU;AACtB,WAAOC,UAAS,KAAKC,OAAOF,SAAS,MAAM,qBAAA;EAC7C;EAEA,IAAcG,wBAAwB;AACpC,WAAOF,UAAS,KAAKC,OAAOC,uBAAuB,MAAM,mCAAA;EAC3D;EAEA,IAAcC,0BAA0B;AACtC,WAAOH,UAAS,KAAKC,OAAOE,yBAAyB,MAAM,qCAAA;EAC7D;EAEA,IAAcC,YAAY;AACxB,WAAOJ,UAAS,KAAKC,OAAOI,kBAAkB,MAAM,uBAAA;EACtD;EAEA,IAAcC,kBAAkB;AAC9B,WAAON,UAAS,KAAKC,OAAOK,iBAAiB,MAAM,6BAAA;EACrD;EAEA,IAAcC,sBAAsB;AAClC,WAAOP,UAAS,KAAKC,OAAOM,qBAAqB,MAAM,iCAAA;EACzD;EAEA,IAAcC,6BAA6B;AACzC,WAAOR,UAAS,KAAKC,OAAOO,4BAA4B,MAAM,oCAAA;EAChE;EAEA,IAAcC,gCAAgC;AAC5C,WAAOT,UAAS,KAAKC,OAAOQ,+BAA+B,MAAM,oCAAA;EACnE;EAEA,IAAcC,gBAAyB;AACrC,WAAOV,UAAS,KAAKC,OAAOS,eAAe,MAAM,4BAAA;EACnD;EAEA,IAAcC,gBAAgB;AAC5B,WAAOX,UAAS,KAAKC,OAAOU,eAAe,MAAM,2BAAA;EACnD;EAEA,IAAcC,qBAAyC;AACrD,WAAOZ,UAAS,KAAKC,OAAOW,oBAAoB,MAAM,gCAAA;EACxD;EAEA,IAAcC,6BAA6B;AACzC,WAAOb,UAAS,KAAKC,OAAOY,4BAA4B,MAAM,wCAAA;EAChE;EAEA,MAAMC,KAAKC,MAA8E;AAEvF,QAAIA,KAAKC,UAAU,KAAKZ,UAAUa,GAAI;AACtC,UAAMC,UAAU,MAAM,KAAKZ,gBAAgBa,gCAAgCJ,IAAAA;AAI3E,QAAIG,UAAU,CAAA,MAAO,KAAKpB,QAAS;AACnC,WAAO,KAAKsB,sBAAsBL,IAAAA;EACpC;EAEA,MAAgBM,uBAAuBC,OAA8C;AACnF,QAAI,CAAC,KAAK1B,qBAAqB;AAE7B,WAAKA,sBAAsB,MAAM2B,kCAAkCC,OAAO;QACxEzB,SAAS;QACT0B,oBAAoB,KAAKd;QACzBe,QAAQ;UACNhB,eAAe,KAAKA;UACpBiB,uBAAuB;UACvBC,QAAQC;QACV;MACF,CAAA;IACF;AACA,UAAMC,WAAW9B,UAAS+B,OAAMT,KAAAA,GAAQ,MAAM,gCAAA;AAC9C,UAAMU,UAAU,IAAIC,eAA4B;MAAEL,QAAQM;IAAkB,CAAA,EAAGC,OAAO;MAAEb,OAAOQ;IAAS,CAAA,EAAGM,MAAK;AAChH,UAAMC,UAAU,MAAM,KAAKzC,oBAAoB0C,OAAO;MAACN;KAAQ;AAC/D,UAAM,CAACO,MAAAA,IAAUF;AACjB,WAAOE;EACT;;;;;;EAOA,MAAgBC,yBAAyBzB,MAAiF;AACxH,UAAM0B,kBAAkBC,QAAQC,IAAIC;AACpC,QAAIC,YAAYJ,eAAAA,EAAkB;AAElC,UAAMK,SAAS,MAAM,KAAKlC,mBAAmBmC,2BAA2B,KAAKjD,SAAS,UAAA;AAItF,UAAMkD,YAAYF,OAAOG,SAAS,CAACC,GAAGC,MAAMD,EAAE,CAAA,IAAKC,EAAE,CAAA,IAAK,IAAI,EAAC,EAAGC,GAAG,EAAC;AACtE,QAAI,CAACJ,UAAW;AAChB,UAAM,CAAA,EAAGK,qBAAAA,IAAyBL;AAClC,UAAMM,eAAevC,KAAKO;AAC1B,UAAMiC,2BAA2BF,wBAAwBC;AACzD,QAAIC,2BAA2B9D,4BAA6B;AAE5D,UAAM+D,SAAS,IAAIvB,eAAiC;MAAEL,QAAQ6B;IAAuB,CAAA,EAAGtB,OAAO;MAC7FuB,MAAM,KAAK5D;MACX0D,QAAQ;MACRG,KAAKL;MACLM,KAAKN,eAAe9D;IACtB,CAAA,EAAG4C,MAAK;AACR,WAAOoB;EACT;EAEA,MAAgBpC,sBAAsBL,MAA8E;AAClH,WAAO,MAAM,KAAK8C,UAAU,yBAAyB,YAAA;AAEnD,YAAM,EAAEvC,OAAOwC,cAAa,IAAK9D,UAAS+D,oBAAoBhD,IAAAA,GAAO,MAAM,oBAAA;AAC3E,YAAMiD,YAAYF,gBAAgB;AAClC,YAAMG,wBAAwB,MAAM,KAAKzD,2BAA2B0D,uBAAuBnD,KAAKoD,OAAOzE,kBAAiBG,gBAAgB;AAExI,YAAMuE,gBAAuC,CAAA;AAG7C,YAAMC,+BAA+B,MAAM,KAAK7B,yBAAyBzB,IAAAA;AACzE,UAAIsD,6BAA8BD,eAAcE,KAAKD,4BAAAA;AAGrD,UAAID,cAAcG,WAAW,KAAKN,sBAAsBM,WAAW,EAAG;AAGtE,YAAMC,wBAAwB,MAAM,KAAKnD,uBAAuB2C,SAAAA;AAChE,UAAIQ,sBAAuBJ,eAAcE,KAAKE,qBAAAA;AAE9C,YAAMC,uBAAuB,MAAMC,6BAA6B,KAAK5E,SAASmE,qBAAAA;AAE9E,YAAMU,kBAA8B,CAAA;AAEpC,YAAMC,8BAA8BX,sBAAsBY,IAAI,CAACC,OAAAA;AAC7D,cAAMC,WAAiCN,qBAAqBO,KAAKC,CAAAA,eAAcA,WAAWvB,SAASoB,GAAG,CAAA,EAAGpB,IAAI;AAC7G,YAAI,CAACqB,SAAU;AACf,cAAMG,oBAAoBC,OAAOC,OAAOL,UAAUM,SAAAA,EAAWC,OAAO,CAACC,KAAKC,MAAMD,MAAME,YAAYD,CAAAA,GAAI,EAAE;AACxG,YAAIC,YAAY,KAAKvF,sBAAsBwF,WAAW,KAAK5F,OAAO,CAAA,KAAMoF,mBAAmB;AACzFP,0BAAgBL,KAAKS,QAAAA;AACrB,iBAAOD;QACT;MACF,CAAA,EAAGa,OAAOC,MAAAA;AAEVxB,oBAAcE,KAAI,GAAIK,eAAAA;AAGtB,YAAMrD,QAAQ,MAAMuE,WAAW9E,MAAM6D,6BAA6BR,eAAe;QAAC,KAAKrE;OAAQ;AAC/F+F,cAAQC,IAAI,cAAczE,KAAAA;AAC1B,YAAM0E,SAAS,MAAM,KAAKnF,2BAA2BS,OAAO,KAAKlB,UAAUa,IAAI,KAAKd,uBAAuB;AAC3G,UAAI6F,OAAOzB,SAAS,GAAG;AACrB,aAAK0B,QAAQC,MAAM,uCAAuCF,MAAAA;AAC1D,cAAMG,uBAAuB7E,MAAM,CAAA;AACnC,cAAM,KAAKb,8BAA8B2F,OAAOD,oBAAAA;MAClD,OAAO;AACL,eAAO7E;MACT;IACF,CAAA;EACF;AACF;;;;;;AEzNA,SAAS+E,YAAAA,iBAAgB;AACzB,SAASC,4BAA4BC,8BAA8B;AACnE,SAEEC,oBACK;;;;;;;;AAWA,IAAMC,wBAAN,cAAoCC,YAAAA;SAAAA;;;EAC/BC;EAEV,IAAcC,eAAe;AAC3B,WAAOC,UAAS,KAAKC,OAAOF,cAAc,MAAM,0BAAA;EAClD;EAEA,IAAcG,kBAAkB;AAC9B,WAAOF,UAAS,KAAKF,kBAAkB,MAAM,6BAAA;EAC/C;EAEA,IAAcK,WAAW;AACvB,WAAOH,UAAS,KAAKC,OAAOE,UAAU,MAAM,sBAAA;EAC9C;EAEA,MAAeC,gBAAgB;AAC7B,UAAM,MAAMA,cAAAA;AACZ,SAAKN,mBAAmB,MAAM,KAAKC,aAAaM,gBAAe;EACjE;EAEA,MAAMC,kBAAkBC,aAAsC;AAC5D,UAAMC,WAAWC,uBAAuBC,QAAQC,aAAa,KAAKT,eAAe,GAAG,KAAKC,QAAQ;AACjG,WAAO,MAAMK,SAASI,gBAAgBL,WAAAA;EACxC;AACF;;;;;;ACxCA,SAASM,YAAAA,iBAAgB;AACzB,SAASC,oBAAoB;AAE7B,SAASC,6BAA6B;;;;;;;;;;;;AAe/B,IAAMC,wBAAN,cAAoCC,YAAAA;SAAAA;;;EACtBC,wBAAwBA,sBAAsB,EAAA;EAEjEC,YACE,EACEC,gBAAgBC,aAAa,YAAe,GAC5CC,oBAAoBD,aAAa,KAAK,GACtCE,oBAAoBF,aAAa,GAAG,GACpCG,wBAAwB,MACxBC,sBAAsB,KACtBC,WAAW,SAAU,IACmB,CAAC,GAC3C;AACA,UAAM;MACJJ;MAAmBC;MAAmBG;MAAUF;MAAuBC;MAAqBL;IAC9F,CAAA;EACF;EAEA,IAAIA,gBAAgB;AAClB,WAAOO,UAAS,KAAKC,OAAOR,eAAe,MAAM,2BAAA;EACnD;EAEA,IAAIS,gBAAgB;AAClB,WAAOF,UAAS,KAAKC,OAAON,mBAAmB,MAAM,+BAAA;EACvD;EAEA,IAAIC,oBAAoB;AACtB,WAAOI,UAAS,KAAKC,OAAOL,mBAAmB,MAAM,+BAAA;EACvD;EAEA,IAAIC,wBAAwB;AAC1B,WAAOG,UAAS,KAAKC,OAAOJ,uBAAuB,MAAM,mCAAA;EAC3D;EAEA,IAAIC,sBAAsB;AACxB,WAAOE,UAAS,KAAKC,OAAOH,qBAAqB,MAAM,iCAAA;EACzD;EAEA,IAAIC,WAAW;AACb,WAAOC,UAAS,KAAKC,OAAOF,UAAU,MAAM,sBAAA;EAC9C;EAEAI,kBAAkBC,aAAyC;AACzD,WAAO,KAAKb,sBACVa,aACA,KAAKF,eACL,KAAKH,UACL,KAAKD,qBACL,KAAKD,uBACL,KAAKD,mBACL,KAAKH,aAAa;EAEtB;AACF;;;;;;;;;;ACvEA,SAASY,YAAAA,iBAAgB;AAIzB,SAASC,kBAAAA,uBAAsB;;;;;;;;AAgB/B,IAAMC,iBAAiB,8BAAO,CAACC,IAAIC,QAAAA,MAA8B;AAC/D,SAAO;IAAC,MAAMC,gBAAeH,eAAeC,EAAAA;IAAK,MAAME,gBAAeH,eAAeE,QAAAA;;AACvF,GAFuB;AAgBhB,IAAME,eAAN,cAAoFC,YAAAA;SAAAA;;;EACzF,IAAIC,UAAU;AACZ,WAAO,KAAKC,QAAQD;EACtB;EAEA,IAAcC,UAAU;AACtB,WAAOC,UAAS,KAAKC,OAAOF,SAAS,MAAM,qBAAA;EAC7C;EAEA,IAAcG,0BAA0B;AACtC,WAAOF,UAAS,KAAKC,OAAOC,yBAAyB,MAAM,qCAAA;EAC7D;EAEA,IAAcC,YAAY;AACxB,WAAOH,UAAS,KAAKC,OAAOG,kBAAkB,MAAM,uBAAA;EACtD;EAEA,IAAcC,kBAAkB;AAC9B,WAAOL,UAAS,KAAKC,OAAOI,iBAAiB,MAAM,6BAAA;EACrD;EAEA,IAAcC,sBAAsB;AAClC,WAAON,UAAS,KAAKC,OAAOK,qBAAqB,MAAM,iCAAA;EACzD;EAEA,IAAcC,gBAAgB;AAC5B,WAAOP,UAAS,KAAKC,OAAOM,eAAe,MAAM,2BAAA;EACnD;EAEAC,qBAAqBC,QAAgD;AACnE,WAAO,CAAA;EACT;;EAGA,MAAMC,2BAA2BC,qBAA4D;AAC3F,UAAM,CAAClB,EAAAA,IAAM,MAAMD,eAAemB,mBAAAA;AAElC,SAAK,MAAM,KAAKT,wBAAwBU,IAAI;MAACnB,GAAGoB;KAAM,GAAGC,SAAS,EAAG,QAAO;AAG5E,WAAO,MAAMC,QAAQC,QAAQ,IAAA;EAC/B;AACF;;;;;;AC9EA,SAASC,YAAAA,iBAAgB;AAEzB,SAASC,oBAAoBC,uBAAuB;AACpD,SAASC,kBAAAA,uBAAsB;;;;;;;;;;;;AAexB,IAAMC,qBAAN,cAAiCC,YAAAA;SAAAA;;;EACtCC,YAAYC,QAAmC;AAC7C,UAAMA,MAAAA;EACR;EAEA,IAAIC,gBAAgB;AAClB,WAAOC,UAAS,KAAKF,OAAOC,eAAe,MAAM,mBAAA;EACnD;EAEA,IAAIE,mBAAmB;AACrB,WAAOD,UAAS,KAAKF,OAAOG,kBAAkB,MAAM,uBAAA;EACtD;EAEA,IAAIC,qBAAqB;AACvB,WAAOF,UAAS,KAAKF,OAAOI,oBAAoB,MAAM,0BAAA;EACxD;EAEA,MAAMC,gCAAgCC,SAAgD;AACpF,WAAO,MAAM,KAAKC,UAAU,mCAAmC,YAAA;AAC7D,YAAMC,YAAYF,QAAQG,QAAQ;AAClC,YAAMC,aAAa,MAAM,KAAKN,mBAAmBO,8BAA8BH,WAAW,UAAA;AAC1F,YAAMI,oBAAoB,MAAMC,gBAAeC,KAAKR,OAAAA;AACpD,aAAO,KAAKS,yBAAyBL,YAAYE,iBAAAA;IACnD,CAAA;EACF;EAEUG,yBAAyBL,YAAuBE,mBAAyBI,UAAU,GAAc;AACzG,UAAMC,WAAW,IAAIC,IAAaR,UAAAA;AAClC,UAAMS,OAAOC,mBAAmBR,iBAAAA;AAChC,UAAMS,eAAeC,gBAAgBL,UAAUE,IAAAA;AAC/C,WAAOE,aAAaE,MAAM,GAAGP,OAAAA;EAC/B;AACF;;;;;;;;;;AClDA,SAASQ,iBAAiB;AAC1B,SAASC,UAAUC,mBAAmB;AACtC,SAASC,YAAAA,iBAAgB;AACzB,SAASC,UAAAA,eAAc;AACvB,SAASC,cAAc;AAEvB,SAASC,uBAAuB;AAEhC,SAASC,2BAA2B;AAIpC,SACEC,wDAEK;AACP,SAASC,6BAA6BC,6BAA6B;AACnE,SAASC,SAAAA,cAAa;;;;;;;;AAYf,IAAMC,gCAAN,MAAMA,uCAAsCC,YAAAA;SAAAA;;;EACjD,OAAwBC,gBAAgB;;;;IAItCC,uBAAuB;;;;IAIvBC,kBAAkB;;;;IAIlBC,4BAA4B;;;;IAI5BC,6BAA6B;EAC/B;;;;;EAMQC,iCAAiC,IAAIC,OAAAA;;;;;EAMrCC;;;;EAKAC,4BAAoC;;;;;EAMpCC,kDAAkD,IAAIH,OAAAA;EAE9D,IAAYI,iBAAiB;AAC3B,WAAOC,UAAS,KAAKC,OAAOF,gBAAgB,MAAM,yCAAA;EACpD;EAEA,IAAYG,sBAAsB;AAChC,WAAOF,UAAS,KAAKC,OAAOC,qBAAqB,MAAM,aAAA;EACzD;EAEA,IAAYC,+BAA+B;AACzC,WAAOH,UAAS,KAAKC,OAAOE,8BAA8B,MAAM,mCAAA;EAClE;EAEA,IAAYC,2BAA2B;AACrCC,WAAO,KAAKC,yBAAwB,CAAA;AACpC,WAAO,KAAKT;EACd;EAEA,IAAYU,oCAAoC;AAC9C,WAAOP,UAAS,KAAKJ,sCAAsC,MAAM,2CAAA;EACnE;EAEA,IAAYY,gCAAgC;AAC1C,WAAOR,UAAS,KAAKC,OAAOO,+BAA+B,MAAM,oCAAA;EACnE;EAEA,MAAeC,gBAAgB;AAC7B,UAAM,MAAMA,cAAAA;AACZ,SAAKb,uCAAuC,MAAMc,gBAAgBC,OAAO;MAAEC,SAAS;IAAS,CAAA;AAG7F,SAAKT,6BAA6BU,GAAG,YAAY,OAAO,EAAEC,SAAQ,MAAE;AAClE,YAAM,KAAKC,sBAAsBD,QAAAA;IACnC,CAAA;AAGA,SAAKf,eAAec,GAAG,YAAY,OAAO,EAAEC,SAAQ,MAAE;AACpD,YAAM,KAAKE,4BAA4BF,QAAAA;IACzC,CAAA;AAGA,SAAKN,8BAA8BK,GAAG,YAAY,OAAO,EAAEC,SAAQ,MAAE;AACnE,YAAM,KAAKG,2BAA2BH,QAAAA;IACxC,CAAA;AAEA,UAAMI,2BAA2B,KAAKC,OAAOC,sBAC3C,kCACA;MAAEC,aAAa;MAA8CC,WAAWC,UAAUC;IAAI,CAAA;AAExFN,8BAA0BO,YAAY,CAACC,aAAAA;AACrCA,eAASC,QAAQ,KAAKvB,wBAAwB;IAChD,CAAA;EACF;EAEA,MAAMwB,uBAAuBC,MAAYC,OAA8D;AACrG,WAAO,MAAM,KAAKC,UAAU,0BAA0B,YAAA;AACpD,aAAO,MAAM,KAAKjC,gDAAgDkC,aAAa,YAAA;AAC7E,cAAMC,2BAAuE,CAAA;AAC7E,YAAIC;AACJ,eAAOD,yBAAyBE,SAASL,OAAO;AAC9C,gBAAMhB,WAAW,MAAM,KAAKP,kCAAkC6B,KAAK;YACjEN,OAAO;YAAKO,OAAO;YAAOH;UAC5B,CAAA;AACA,cAAIpB,SAASqB,WAAW,EAAG;AAC3BD,mBAASpB,SAASwB,GAAG,EAAC,GAAIC;AAC1B,gBAAMC,eAAe1B,SAAS2B,IAAIC,CAAAA,YAAWC,iDAAiDD,OAAAA,CAAAA,EAAUE,OAAOC,OAAAA;AAC/GZ,mCAAyBa,KAAI,GAAIN,YAAAA;QACnC;AACA,cAAMO,uBAAuB,MAAMC,QAAQC,IACzChB,yBAAyBQ,IAAIS,CAAAA,OAAMC,sBAAsB,KAAK5C,mCAAmC2C,GAAGE,KAAK,CAAA,CAAA;AAE3G,eAAOL,qBAAqBH,OAAOC,OAAAA;MACrC,GAAG1D,+BAA8BE,cAAcE,gBAAgB;IACjE,CAAA;EACF;EAEA,MAAce,2BAA2B;AACvC,QAAI,KAAKZ,+BAA+B2D,SAAQ,EAAI;AACpD,UAAM,KAAK3D,+BAA+BsC,aAAa,YAAA;AACrD,YAAMlB,WAAY,MAAM,KAAKlB,sCAAsCqD,IAAAA,KAAU,CAAA;AAC7E,YAAMK,sBAAsBC,SAASzC,UAAU6B,gDAAAA;AAC/C,WAAK9C,4BAA4ByD,oBAAoBnB;IACvD,CAAA;EACF;EAEA,MAAcqB,mCAAmC1C,UAA2F;AAC1I,UAAM2C,uBAAuBF,SAASzC,UAAU6B,gDAAAA;AAChD,UAAMe,4BAA4BD,qBAAqBhB,IAAIC,CAAAA,YAAWA,QAAQU,KAAK;AACnF,UAAMO,wBAAwB,MAAM,KAAK5D,eAAe6D,IAAIF,yBAAAA;AAC5D,UAAMG,6BAA6B,IAAIC,IAAIH,sBAAsBlB,IAAIsB,CAAAA,SAAQA,KAAKX,KAAK,CAAA;AACvF,UAAMY,2BAA2BP,qBAAqBb,OAAOmB,CAAAA,SAAQ,CAACF,2BAA2BI,IAAIF,KAAKX,KAAK,CAAA;AAC/G,WAAOY;EACT;EAEA,MAAcjD,sBAAsBD,UAAsC;AACxE,WAAO,MAAM,KAAKiB,UAAU,yBAAyB,YAAA;AACnD,aAAO,MAAM,KAAKjC,gDAAgDkC,aAAa,YAAA;AAE7E,cAAMkC,0BAA0B,MAAM,KAAKV,mCAAmC1C,QAAAA;AAE9E,cAAMqD,mCAAmC,MAAMnB,QAAQC,IAAIiB,wBAAwBzB,IAAI,CAACS,OAAAA;AACtF,iBAAOC,sBAAsB,KAAKhD,8BAA8B+C,GAAGE,KAAK;QAC1E,CAAA,CAAA,GAAKR,OAAOC,OAAAA;AAEZ,cAAMuB,oBAAoB,MAAMC,YAAYF,iCAAiC,OAAOjB,OAAAA;AAClF,gBAAMoB,SAAS,MAAMC,oBAAoBrB,IAAI,KAAKhD,oBAAoBsE,EAAE;AACxE,iBAAOF,OAAOnC,SAAS,IAAI,QAAQ;QACrC,CAAA;AACA,cAAM,KAAK5B,kCAAkCkE,OAAOC,4BAA4BN,iBAAAA,CAAAA;MAClF,GAAGjF,+BAA8BE,cAAcC,qBAAqB;IACtE,CAAA;EACF;EAEA,MAAc0B,4BAA4BF,UAAsC;AAC9E,WAAO,MAAM,KAAK6D,mBAAmB7D,UAAU,6BAAA;EACjD;EAEA,MAAcG,2BAA2BH,UAAsC;AAC7E,WAAO,MAAM,KAAK6D,mBAAmB7D,UAAU,4BAAA;EACjD;EAEA,MAAc6D,mBACZ7D,UACA8D,UACA;AACA,WAAO,MAAM,KAAK7C,UAAU6C,UAAU,YAAA;AACpC,aAAO,MAAM,KAAK9E,gDAAgDkC,aAAa,YAAA;AAC7E,cAAMQ,eAAee,SAASzC,UAAU6B,gDAAAA;AACxC,cAAM,KAAKpC,kCAAkCsE,OAAOrC,aAAaC,IAAIS,CAAAA,OAAMA,GAAGE,KAAK,CAAA;MACrF,GAAGjE,+BAA8BE,cAAcuF,QAAAA,CAAS;IAC1D,CAAA;EACF;AACF;;;;;;AC3MA,SAASE,YAAAA,iBAAgB;AACzB,SAASC,UAAAA,eAAc;AAIvB,SAASC,8BAA8B;AACvC,SAASC,8BAA8B;AACvC,SAASC,2BAA2B;AAIpC,SAASC,4BAA4BC,0BAAAA,+BAA8B;AAE5D,IAAMC,kCAAkC,8BAAOC,OAA0BC,WAA8BC,WAAAA;AAE5G,QAAMC,YAAY,MAAMF,UAAUG,IAAIJ,MAAMK,cAAc;AAE1D,QAAMC,eAAeC,UAASJ,WAAWK,sBAAAA;AAEzC,QAAMC,+BAA+BH,aAAaI,OAAOC,CAAAA,OAAMC,uBAAuBD,IAAIE,uBAAAA,CAAAA;AAE1F,QAAMC,gCAAgC,MAAMC,kCAAkCN,4BAAAA;AAC9E,UAAQ,MAAMO,QAAQC,IAAIH,8BAA8BI,IAAI,OAAOP,OAAAA;AAEjE,UAAMQ,oBAAoBL,8BACvBM,QAAQC,kCAAAA,EACRX,OAAOY,OAAAA;AAEV,UAAMC,WAAW,MAAMtB,UAAUG,IAAIe,iBAAAA;AAErC,UAAMK,eAAejB,UAASgB,UAAUE,0BAAAA,EAErCf,OAAOgB,CAAAA,MAAKA,EAAExB,WAAWA,MAAAA,EAEzBQ,OAAOgB,CAAAA,MAAKf,GAAGgB,UAAUC,SAASF,EAAEG,IAAI,CAAA;AAE3C,WAAOL;EACT,CAAA,CAAA,GAAKM,KAAI;AACX,GAzB+C;AA2B/C,IAAMf,oCAAoC,8BAAOgB,QAAAA;AAC/C,QAAMC,iBAAiB,MAAMhB,QAAQC,IAAIc,IAAIb,IAAIP,CAAAA,OAAMsB,oBAAoBC,MAAMvB,EAAAA,EAAIwB,SAAQ,CAAA,CAAA;AAC7F,SAAOJ,IAAIrB,OAAO,CAAC0B,GAAGC,UAAUL,eAAeK,KAAAA,CAAM;AACvD,GAH0C;AAK1C,IAAMhB,qCAAqC,wBAACV,OAAAA;AAC1C,SAAOA,GAAG2B,gBAAgBpB,IAAI,CAACqB,QAAQF,UAAUE,WAAW1B,0BAAyBF,GAAGN,eAAegC,KAAAA,IAASG,MAAAA;AAClH,GAF2C;;;AC7C3C,SAASC,YAAAA,iBAAgB;AACzB,SAASC,YAAAA,iBAAgB;AACzB,SACWC,iBACJ;AAEP,SACEC,gBAAAA,eAAcC,0BACdC,iCACK;AACP,SACEC,0CACAC,mBAAmBC,mBAEd;AACP,SAASC,kBAAAA,uBAAsB;AAK/B,SACEC,6BAA6BC,4CAC7BC,oDAAoDC,8BAAAA,6BAAuDC,iCAC3GC,mCAEK;AACP,SAASC,SAAAA,cAAa;AACtB,SAASC,gBAAgB;A;;;;;;;;;;;AAgBzB,IAAMC,mBAAmB,MAAO,KAAK,KAAK;AAC1C,IAAMC,sBAAsB,MAAO;AACnC,IAAMC,0BAA0B;AAGzB,IAAMC,wBAAN,cAAoCC,YAAAA;SAAAA;;;;EAE/BC,wBAA0CC;;;;;;;;EAQ1CC,aAAmC,IAAIC,YAAAA;EACvCC,cAAc,IAAIC,SAA0B;IAAEC,KAAKT;EAAwB,CAAA;EAC3EU,eAAe,IAAIC,OAAAA;EAE7BC,YAAYC,QAAqC;AAC/C,UAAMA,MAAAA;AACN,SAAKC,cAAcC,GAAG,eAAe,YAAA;AACnC,YAAM,KAAKC,YAAW;IACxB,CAAA;EACF;EAEA,IAAcC,iBAAiB;AAC7B,WAAOC,UAAS,KAAKL,OAAOI,gBAAgB,MAAM,wBAAA;EACpD;EAEA,IAAcH,gBAAgB;AAC5B,WAAOI,UAAS,KAAKL,OAAOC,eAAe,MAAM,uBAAA;EACnD;EAEA,IAAcK,mBAAmB;AAC/B,WAAOD,UAAS,KAAKL,OAAOM,kBAAkB,MAAM,0BAAA;EACtD;EAEA,IAAcC,4BAA4B;AACxC,WAAOF,UAAS,KAAKL,OAAOO,2BAA2B,MAAM,mCAAA;EAC/D;EAEA,MAAeC,gBAA+B;AAC5C,UAAMC,OAAO,MAAM,KAAKR,cAAcQ,KAAI;AAC1C,UAAMC,WAAW,MAAMC,gBAAeC,KAAKH,IAAAA;AAC3C,QAAIA,MAAMI,UAAUtB,OAAW;AAC/B,UAAM,KAAKuB,aAAaJ,QAAAA;AACxB,UAAM,KAAKP,YAAY,IAAA;EACzB;EAEA,MAAMY,2BAA2BC,SAAkBC,QAAiE;AAClH,UAAMC,QAAQC,QAAO;AACrBd,IAAAA,UAASY,WAAW,YAAY,MAAM,2CAA2CA,MAAAA,EAAQ;AACzF,UAAMG,UAAU,KAAK5B,WAAW6B,IAAIL,OAAAA;AACpC,WAAOI,WAAW,CAAA;EACpB;EAEA,MAAME,8BAA8BT,OAAeI,QAAoC;AACrF,WAAO,MAAM,KAAKM,UAAU,iCAAiC,YAAA;AAC3DlB,MAAAA,UAASY,WAAW,YAAY,MAAM,2CAA2CA,MAAAA,EAAQ;AACzF,YAAMG,UAAU,KAAK5B,WAAWgC,kBAAkBX,KAAAA;AAClD,YAAMY,aAAa;WAAIL;;AACvB,YAAMM,kBAAkB,MAAM,KAAKC,mBAAmBF,YAAY,KAAKnB,gBAAgB;AACvF,aAAOoB;IACT,CAAA;EACF;EAEA,MAAME,iBAAiBf,OAAeI,QAAgBD,SAAoC;AACxF,UAAMS,aAAa,MAAM,KAAKH,8BAA8BT,OAAOI,MAAAA;AACnE,WAAOQ,WAAWI,SAASb,OAAAA;EAC7B;EAEA,MAAcW,mBACZF,YACAnB,kBACAwB,uBAA+B,IACX;AAIpB,UAAMC,sBAAwC,MAAMb,QAAQc,IAC1DP,WAAWQ,IAAI,OAAOC,cAAAA;AAEpB,YAAMC,QAAQ,KAAKzC,YAAY2B,IAAIa,SAAAA;AACnC,UAAIC,UAAU5C,QAAW;AAEvB,cAAM6C,cAAc,MAAM9B,iBAAiB+B,sBAAsB,GAAGH,SAAAA,EAAW;AAC/E,YAAIE,cAAc,IAAI;AAEpB,eAAK1C,YAAY4C,IAAIJ,WAAWE,aAAa;YAAEG,KAAKtD;UAAiB,CAAA;QACvE,OAAO;AACL,eAAKS,YAAY4C,IAAIJ,WAAWE,aAAa;YAAEG,KAAKrD;UAAoB,CAAA;QAC1E;AACA,eAAO;UAAEgD;UAAWC,OAAOC;QAAY;MACzC,OAAO;AACL,eAAO;UAAEF;UAAWC;QAAM;MAC5B;IACF,CAAA,CAAA;AAIF,WAAOJ,oBACJS,OAAO,CAAC,EAAEL,MAAK,MAAOA,SAASL,oBAAAA,EAC/BG,IAAI,CAAC,EAAEC,UAAS,MAAOA,SAAAA;EAC5B;EAEA,MAAcO,aAAaC,SAA8B;AACvD,UAAMC,QAAQ,KAAKnD,WAAWoD,UAAS;AACvC,UAAMC,UAAU,IAAIlC,gBAAiE;MAAEmC,QAAQC;IAAgC,CAAA,EAC5HC,OAAO;MAAEC,cAAcP;MAASC;IAAM,CAAA,EACtCO,MAAK;AACR,UAAM,KAAK3C,0BAA0B4C,OAAO;MAACN;KAAQ;EACvD;EAEA,MAAc/B,aAAa4B,SAA8B;AACvD,UAAMU,eAAe/C,UAASgD,6BAA6B,MAAM,KAAKjD,eAAeiB,IAAI;MAACqB;KAAQ,KAAK,CAAA,CAAE,GAAG,MAAM,SAASA,OAAAA,YAAmB;AAC9I,UAAMY,kBAAkBF,aAAavC;AAErC,UAAM0C,OAA6B;MAAE,GAAGC;IAAyC;AACjF,WAAO,MAAM;AACX,YAAMC,YAAY,wBAACC,MAAAA;AACjB,cAAMf,SAAQgB,mDAAmDD,CAAAA;AACjE,eAAOf,SAAQ,OAAO;MACxB,GAHkB;AAIlB,YAAMA,QAAQ,MAAMiB,kBAAkB,KAAKrD,2BAA2BkD,WAAWF,IAAAA;AACjF,UAAIM,4BAAmDlB,KAAAA,GAAQ;AAC7D,cAAMmB,WAAW,MAAM,KAAK1D,eAAeiB,IAAI;UAACsB,MAAMM;SAAa,KAAK,CAAA;AACxE,cAAMc,eAAeC,2CAA2CF,OAAAA;AAChE,YAAIC,cAAc;AAChB,gBAAME,kBAAkBF,aAAalD;AACrC,cAAIoD,mBAAmBX,iBAAiB;AACtC,kBAAMY,OAAOvB,MAAMA;AACnB,iBAAKnD,aAAa,IAAIC,YAAYyE,IAAAA;AAClC,iBAAK5E,wBAAwByE,aAAaI;AAC1C;UACF;QACF;MACF,OAAO;AAEL;MACF;AACAZ,WAAKa,OAAO;IACd;EACF;EAEA,MAAcjE,YAAYkE,kBAAkB,OAAsB;AAChE,QAAI,KAAKxE,aAAayE,SAAQ,GAAI;AAChC;IACF;AACA,UAAM,KAAKzE,aAAa0E,aAAa,YAAA;AACnC,aAAO,MAAM,KAAKhD,UAAU,eAAe,YAAA;AACzC,cAAMiD,cAAc,MAAM,KAAKvE,cAAcQ,KAAI;AACjD,cAAMgE,kBAAkB,MAAM9D,gBAAeC,KAAK4D,WAAAA;AAClD,cAAME,SAAS,MAAMC,cAAa,KAAKvE,gBAAgB;UAAC,IAAIwE,yBAAyB,UAAA;WAAcH,iBAAiB,KAAKnF,qBAAqB;AAC9I,cAAMuF,qBAAqBC,UAASJ,OAAOK,KAAKC,yBAAAA,GAA4BC,WAAW,CAAA,GAAIC,2BAAAA;AAC3F,YAAIV,YAAY3D,UAAUtB,OAAW;AACrC,cAAM4F,sBAAsBX,YAAY3D;AACxC,YAAIwD,gBAAiB,MAAKe,QAAQC,KAAK,4BAA4BF,mBAAAA,EAAqB;AACxF,mBAAWG,qBAAqBT,oBAAoB;AAClD,gBAAM,EAAEU,KAAKC,IAAG,IAAKF;AACrB,gBAAMG,QAAQD;AACd,gBAAME,OAAOH;AACb,gBAAMvE,UAAU2E,UAAUL,mBAAmBM,IAAAA;AAC7C,cAAIH,UAAUlG,UAAamG,SAASnG,UAAayB,YAAYzB,QAAW;AACtE,iBAAKC,WAAW2D,OAAOnC,SAASyE,OAAOC,IAAAA;UACzC;QACF;AAOA,aAAKpG,wBAAwBmF;MAC/B,CAAA;IACF,CAAA;EACF;AACF;;;;;;;;;;AC5NA,SAASoB,YAAY;AAErB,SAASC,iBAAiB;AAG1B,SAASC,2BAA2BC,6BAA6B;AAEjE,SAASC,kBAAkB;AAYpB,IAAMC,kBAAN,cAA8BC,KAAAA;EAnBrC,OAmBqCA;;;EAC3BC;EAER,YAAsBC,QAA+B;AACnD,UAAMA,MAAAA;AACN,SAAKD,YAAYC,OAAOC;EAC1B;EAEA,IAAIC,KAAc;AAChB,WAAO,KAAKF,OAAOE;EACrB;EAEA,IAAIC,SAAyB;AAC3B,WAAO,KAAKH,OAAOG;EACrB;EAEA,OAAOC,OAAO,EACZF,IAAIC,QAAQE,QAAQC,eAAeC,cAAa,GACuB;AACvE,UAAMC,kBAAkBC,WAAWP,EAAAA;AACnC,UAAMD,WAA2BS,sBAAsBC,QAAQH,iBAAiBL,MAAAA;AAChF,WAAO,IAAI,KAAK;MACdD;MAAID;MAAUE;MAAQE;MAAQC;MAAeC;IAC/C,CAAA;EACF;EAEA,MAAMK,SAA0B;AAC9B,WAAO,MAAM,KAAKb,UAAUa,OAAM;EACpC;EAEA,MAAMC,sBAAsBC,SAAkC;AAC5D,WAAO,MAAM,KAAKf,UAAUc,sBAAsBJ,WAAWK,OAAAA,CAAAA;EAC/D;EAEA,MAAMC,eAAeD,SAAkC;AACrD,WAAO,MAAM,KAAKf,UAAUgB,eAAeN,WAAWK,OAAAA,CAAAA;EACxD;EAEA,MAAME,SAASC,QAAgBC,QAAkC;AAC/D,UAAMC,SAAS,MAAM,KAAKpB,UAAUiB,SAASP,WAAWQ,MAAAA,GAASC,MAAAA;AACjE,UAAMC,OAAOC,KAAI;AACjB,WAAO;EACT;EAEA,MAAMC,UAA4B;AAChC,WAAOC,UAAU,MAAM,KAAKvB,UAAUsB,QAAO,CAAA;EAC/C;EAEA,MAAME,sBAAuC;AAC3C,WAAO,MAAM,KAAKxB,UAAUwB,oBAAmB;EACjD;EAEA,MAAMC,eAAgC;AACpC,WAAO,MAAM,KAAKzB,UAAUyB,aAAY;EAC1C;EAEA,MAAMC,gBAAkC;AACtC,WAAOH,UAAU,MAAM,KAAKvB,UAAU0B,cAAa,CAAA;EACrD;EAEA,MAAMC,sBAAuC;AAC3C,WAAO,MAAM,KAAK3B,UAAU2B,oBAAmB;EACjD;EAEA,MAAMC,UAA2B;AAC/B,WAAO,MAAM,KAAK5B,UAAU4B,QAAO;EACrC;EAEA,MAAMC,gBAAgBC,QAAiC;AACrD,WAAO,MAAM,KAAK9B,UAAU6B,gBAAgBnB,WAAWoB,MAAAA,CAAAA;EACzD;EAEA,MAAMC,YAAYC,MAAgC;AAChD,UAAMZ,SAAS,MAAM,KAAKpB,UAAU+B,YAAYC,IAAAA;AAChD,UAAMZ,OAAOC,KAAI;AACjB,WAAO;EACT;EAEA,MAAMY,kBAAmC;AACvC,WAAO,MAAM,KAAKjC,UAAUiC,gBAAe;EAC7C;EAEA,MAAMC,sBAAuC;AAC3C,WAAO,MAAM,KAAKlC,UAAUkC,oBAAmB;EACjD;EAEA,MAAMC,cAAcH,MAAgC;AAClD,UAAMZ,SAAS,MAAM,KAAKpB,UAAUmC,cAAcH,IAAAA;AAClD,UAAMZ,OAAOC,KAAI;AACjB,WAAO;EACT;EAEA,MAAMe,YAA6B;AACjC,WAAO,MAAM,KAAKpC,UAAUoC,UAAS;EACvC;EAEA,MAAMC,kBAAkBP,QAAiC;AACvD,WAAO,MAAM,KAAK9B,UAAUqC,kBAAkB3B,WAAWoB,MAAAA,CAAAA;EAC3D;AACF;;;ACtHA,SAASQ,YAAAA,kBAAgB;AAEzB,SAASC,eAAAA,oBAAmB;AAC5B,SAASC,WAAWC,cAAc;AAElC,SAASC,kBAAAA,uBAAsB;AAO/B,SACEC,uBAAAA,sBAAqBC,+BAAAA,8BACrBC,2BACK;AACP,SAASC,YAAAA,iBAAgB;AAElB,IAAMC,8BAAN,MAAMA,qCAAoCC,aAAAA;EAlBjD,OAkBiDA;;;EACrCC,uBAAuB,IAAIC,UAAoC;IAAEC,KAAK;EAAO,CAAA;EAC7EC;EACAC;EACAC;EAEV,YAAsBC,QAAgC;AACpD,UAAM,CAAC,CAAA;AACP,UAAM,EAAEC,gBAAgBC,WAAWC,KAAI,IAAKH;AAC5C,SAAKH,kBAAkBK;AACvB,SAAKH,QAAQI;AACb,SAAKL,oBAAoB;MAAEM,IAAID,KAAKE;IAAM;EAC5C;EAEA,IAAIH,YAA+B;AAAE,WAAO,KAAKL;EAAgB;EAEjE,IAAIS,sBAA2C;AAAE,WAAO,KAAKR;EAAkB;EAE/E,aAAaS,OAAOP,QAAsE;AACxF,UAAMQ,QAAQC,QAAO;AACrB,WAAO,IAAIjB,6BAA4BQ,MAAAA;EACzC;EAEA,MAAMU,IAAIC,OAA2C;AAEnDC,IAAAA,WAAS,KAAKb,MAAMY,SAASA,OAAO,MAAM,mDAAmDA,KAAAA,GAAQ;AACrG,UAAME,SAAS,KAAKnB,qBAAqBgB,IAAIC,KAAAA;AAC7C,QAAIE,OAAQ,QAAOA;AAEnB,UAAMC,gBAAgB,KAAKf;AAC3B,UAAMgB,mBAAmB,MAAMC,gBAAeC,KAAKH,aAAAA;AACnD,QAAII,gBAAgB,MAAM,KAAKrB,gBAAgBa,IAAI;MAACK;KAAiB,GAAGI,GAAG,CAAA;AAC3E,WAAOC,UAAUF,YAAAA,GAAe;AAC9BN,MAAAA,WAASS,qBAAoBH,YAAAA,GAAe,MAAM,8CAA8CA,cAAcI,KAAAA,GAAQ;AACtH,UAAIC,oBAAoBL,YAAAA,GAAe;AACrC,aAAKxB,qBAAqB8B,IAAIN,aAAaP,OAAOO,YAAAA;AAClD,YAAIA,aAAaP,UAAUA,OAAO;AAChC,iBAAOO;QACT;AACA,cAAM,EAAEO,SAAQ,IAAKP;AACrB,YAAIQ,OAAOD,QAAAA,EAAW;AACtBP,wBAAgB,MAAM,KAAKrB,gBAAgBa,IAAI;UAACe;SAAS,GAAGN,GAAG,CAAA;MACjE;IACF;AACA,UAAM,IAAIQ,MAAM,oBAAoBhB,KAAAA,EAAO;EAC7C;EAEA,MAAMR,OAAmC;AACvC,WAAO,MAAMK,QAAQC,QAAQ,KAAKV,KAAK;EACzC;EAEA,MAAM6B,KAAKjB,OAAuD;AAChE,UAAMO,eAAeP;AACrB,UAAMkB,kBAAkBX,eAAe;AACvC,WAAO,MAAM,KAAKR,IAAImB,eAAAA;EACxB;;;EAIA,MAAMJ,SAASd,QAA4BmB,QAAWC,QAAgB,GAAiC;AACrG,UAAMC,UAA+B,CAAA;AACrC,QAAId,eAA8CE,UAAUT,KAAAA,IAAU,MAAM,KAAKD,IAAIC,KAAAA,IAAU,KAAKZ;AACpG,WAAOmB,gBAAgBc,QAAQC,SAASF,OAAO;AAC7C,UAAIR,oBAAoBL,YAAAA,GAAe;AACrCc,gBAAQE,KAAKhB,YAAAA;AACb,cAAM,EAAEO,SAAQ,IAAKP;AACrB,YAAIQ,OAAOD,QAAAA,EAAW;AACtB,cAAMU,YAAY,MAAM,KAAKtC,gBAAgBa,IAAI;UAACe;SAAS;AAC3DP,uBAAekB,6BAA4BD,UAAU,CAAA,CAAE;MACzD,OAAO;AACL,cAAMlB,OAAOD,gBAAeC,KAAKC,YAAAA;AACjCN,QAAAA,WAASS,qBAAoBH,YAAAA,GAAe,MAAM,8CAA8CD,IAAAA,GAAO;MACzG;IACF;AACA,WAAOe;EACT;EAEA,MAAMK,WAAWlC,MAAwC;AAEvD,UAAMK,QAAQC,QAAO;AACrB,SAAKV,QAAQI;AACb,SAAK,KAAKmC,KAAK,eAAe;MAAEC,QAAQ;QAACpC;;IAAM,CAAA;EACjD;AACF;","names":["assertEx","toHex","analyzeChain","BalanceAnalyzer","isChainSummaryBalances","toPositiveBigInt","BaseEmitter","span","spanAsync","Mutex","BaseService","BaseEmitter","singletonInitMutex","Mutex","singletons","globalThis","name","constructor","create","params","result","Error","createHandler","initSingleton","runExclusive","span","fn","tracer","spanAsync","BaseAccountableService","creatableService","XyoChainAccountBalanceService","BaseService","_balances","_previousHead","chainArchivist","assertEx","params","getBalance","address","toPositiveBigInt","positive","toHex","getBalances","result","entries","Object","balance","sync","head","analysis","analyzeChain","BalanceAnalyzer","tracer","find","isChainSummaryBalances","balances","BaseEthProvider","eth_accounts","Error","eth_blockNumber","eth_call","_transaction","_blockNumber","eth_clearSubscriptions","_keepSyncing","eth_coinbase","eth_compileLLL","_code","eth_compileSerpent","eth_compileSolidity","eth_estimateGas","eth_feeHistory","_blockCount","_newestBlock","_rewardPercentiles","eth_gasPrice","eth_getBalance","_address","eth_getBlockByHash","_blockHash","_hydrated","eth_getBlockByNumber","eth_getBlockTransactionCountByHash","eth_getBlockTransactionCountByNumber","eth_getCode","eth_getCompilers","eth_getFilterChanges","_filterIdentifier","eth_getFilterLogs","eth_getLogs","_filter","eth_getStorageAt","_storageSlot","eth_getTransactionByBlockHashAndIndex","_transactionIndex","eth_getTransactionByBlockNumberAndIndex","eth_getTransactionByHash","_transactionHash","eth_getTransactionCount","eth_getTransactionReceipt","eth_getUncleByBlockHashAndIndex","_uncleIndex","eth_getUncleByBlockNumberAndIndex","eth_getUncleCountByBlockHash","eth_getUncleCountByBlockNumber","eth_getWork","eth_hashrate","eth_maxPriorityFeePerGas","eth_mining","eth_newBlockFilter","eth_newFilter","eth_newPendingTransactionFilter","eth_protocolVersion","eth_sendRawTransaction","eth_sendTransaction","eth_sign","_message","eth_signTransaction","eth_submitHashrate","_hashRate","_id","eth_submitWork","_nonce","_hash","_digest","eth_subscribe","_params","eth_syncing","eth_uninstallFilter","eth_unsubscribe","_subscriptionId","assertEx","exists","hexToBigInt","toHex","isUndefined","FixedPercentageBlockRewardDiviner","FixedPercentageBlockRewardDivinerConfigSchema","buildBlock","PayloadBuilder","asBlockBoundWitness","BlockNumberSchema","ChainStakeIntentSchema","assertEx","hexFromBigInt","XYO_ZERO_ADDRESS","HydratedTransactionWrapper","MicroXL1","mXL1ToXL1","TransferSchema","XL1","transactionRequiredGas","generateTransactionTransfers","address","transactions","txs","Promise","all","map","tx","HydratedTransactionWrapper","parse","txBaseFeeCosts","boundWitness","from","XL1","mXL1ToXL1","fees","base","txGasCosts","requiredGas","transactionRequiredGas","data","totalGasCostInMicroXL1","MicroXL1","gasPrice","payloads","Object","entries","amount","payload","schema","TransferSchema","epoch","Date","now","transfers","XYO_ZERO_ADDRESS","hexFromBigInt","fromPayload","assertEx","find","p","DEFAULT_BLOCK_SIZE","XYO_PRODUCER_RESTAKE_DURATION","XYO_PRODUCER_RESTAKE_WINDOW","XyoBlockProducer","BaseService","_blockRewardDiviner","DefaultBlockSize","address","account","assertEx","params","accountBalanceService","chainFinalizedArchivist","chainInfo","chainInformation","electionService","pendingTransactions","pendingTransactionsService","rejectedTransactionsArchivist","rewardAddress","rewardService","stakeIntentService","validateHydratedBlockState","next","head","chain","id","leaders","getCreatorCommitteeForNextBlock","proposeNextValidBlock","getBlockRewardTransfer","block","FixedPercentageBlockRewardDiviner","create","blockRewardService","config","rewardPercentageRatio","schema","FixedPercentageBlockRewardDivinerConfigSchema","blockHex","toHex","blockId","PayloadBuilder","BlockNumberSchema","fields","build","rewards","divine","reward","getProducerRedeclaration","redeclareIntent","process","env","XYO_PRODUCER_REDECLARE_INTENT","isUndefined","ranges","getDeclaredCandidateRanges","lastRange","toSorted","a","b","at","currentDeclarationEnd","currentBlock","timeToProducerExpiration","intent","ChainStakeIntentSchema","from","nbf","exp","spanAsync","previousBlock","asBlockBoundWitness","nextBlock","nextBlockTransactions","getPendingTransactions","_hash","blockPayloads","producerRedeclarationPayload","push","length","rewardTransferPayload","transactionTransfers","generateTransactionTransfers","fundedTransfers","fundedNextBlockTransactions","map","tx","transfer","find","txTransfer","totalTransferCost","Object","values","transfers","reduce","acc","t","hexToBigInt","getBalance","filter","exists","buildBlock","console","log","errors","logger","error","rejectedTransactions","insert","assertEx","XyoChainRewards__factory","XyoChainRewardsFactory","toEthAddress","EvmBlockRewardService","BaseService","_contractAddress","chainService","assertEx","params","contractAddress","provider","createHandler","rewardsContract","getRewardForBlock","blockNumber","contract","XyoChainRewardsFactory","connect","toEthAddress","calcBlockReward","assertEx","toFixedPoint","rewardFromBlockNumber","XyoBlockRewardService","BaseService","rewardFromBlockNumber","constructor","creatorReward","toFixedPoint","initialStepReward","minRewardPerBlock","stepFactorDenominator","stepFactorNumerator","stepSize","assertEx","params","initialReward","getRewardForBlock","blockNumber","assertEx","PayloadBuilder","addStorageMeta","tx","payloads","PayloadBuilder","XyoValidator","BaseService","address","account","assertEx","params","chainFinalizedArchivist","chainInfo","chainInformation","electionService","pendingTransactions","rewardService","validatePendingBlock","_block","validatePendingTransaction","hydratedTransaction","get","_hash","length","Promise","resolve","assertEx","hexToLast4BytesInt","shuffleWithSeed","PayloadBuilder","XyoElectionService","BaseService","constructor","params","chainIterator","assertEx","chainStakeViewer","stakeIntentService","getCreatorCommitteeForNextBlock","current","spanAsync","nextBlock","block","candidates","getDeclaredCandidatesForBlock","previousBlockHash","PayloadBuilder","hash","generateCreatorCommittee","maxSize","creators","Set","seed","hexToLast4BytesInt","creatorArray","shuffleWithSeed","slice","ValueType","filterAs","filterAsync","assertEx","exists","forget","MemoryArchivist","validateTransaction","asOptionalTransactionBoundWitnessWithStorageMeta","flattenHydratedTransactions","tryHydrateTransaction","Mutex","XyoPendingTransactionsService","BaseService","MutexPriority","InsertNewTransactions","ReadTransactions","RemoveRejectedTransactions","RemoveFinalizedTransactions","_countPendingTransactionsMutex","Mutex","_curatedPendingTransactionsArchivist","_pendingTransactionsCount","_updateCuratedPendingTransactionsArchivistMutex","chainArchivist","assertEx","params","chainIdentification","pendingTransactionsArchivist","pendingTransactionsCount","forget","countPendingTransactions","pendingTransactionsLocalArchivist","rejectedTransactionsArchivist","createHandler","MemoryArchivist","create","account","on","payloads","insertNewTransactions","removeFinalizedTransactions","removeRejectedTransactions","pendingTransactionsGauge","meter","createObservableGauge","description","valueType","ValueType","INT","addCallback","observer","observe","getPendingTransactions","head","limit","spanAsync","runExclusive","foundPendingTransactions","cursor","length","next","order","at","_sequence","transactions","map","payload","asOptionalTransactionBoundWitnessWithStorageMeta","filter","exists","push","hydratedTransactions","Promise","all","tx","tryHydrateTransaction","_hash","isLocked","pendingTransactions","filterAs","filterAlreadyFinalizedTransactions","incomingTransactions","incomingTransactionHashes","finalizedTransactions","get","finalizedTransactionHashes","Set","item","nonFinalizedTransactions","has","unprocessedTransactions","hydratedUnprocessedTransactions","validTransactions","filterAsync","errors","validateTransaction","id","insert","flattenHydratedTransactions","removeTransactions","priority","delete","filterAs","exists","asOptionalBoundWitness","payloadSchemasContains","BoundWitnessWrapper","asOptionalChainStakeIntent","ChainStakeIntentSchema","getBlockSignedStakeDeclarations","block","archivist","intent","blockData","get","payload_hashes","bwsFromBlock","filterAs","asOptionalBoundWitness","bwsFromBlockWithDeclarations","filter","bw","payloadSchemasContains","ChainStakeIntentSchema","validBlockBwsWithDeclarations","filterToValidSignedBoundWitnesses","Promise","all","map","stakeIntentHashes","flatMap","mapBoundWitnessToStakeIntentHashes","exists","payloads","stakeIntents","asOptionalChainStakeIntent","p","addresses","includes","from","flat","bws","validBwIndexes","BoundWitnessWrapper","parse","getValid","_","index","payload_schemas","schema","undefined","filterAs","assertEx","asAddress","analyzeChain","ChainStakeIntentAnalyzer","isChainSummaryStakeIntent","DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS","findFirstMatching","IntervalMap","PayloadBuilder","asOptionalBlockBoundWitness","asOptionalBlockBoundWitnessWithStorageMeta","asOptionalChainIndexingServiceStateWithStorageMeta","asOptionalChainStakeIntent","ChainIndexingServiceStateSchema","isChainIndexingServiceState","Mutex","LRUCache","ACTIVE_STAKE_TTL","NO_ACTIVE_STAKE_TTL","STAKE_CACHE_MAX_ENTRIES","XyoStakeIntentService","BaseService","_lastIndexedBlockHash","undefined","_producers","IntervalMap","_stakeCache","LRUCache","max","_updateMutex","Mutex","constructor","params","chainIterator","on","updateIndex","chainArchivist","assertEx","chainStakeViewer","stakeIntentStateArchivist","createHandler","head","headHash","PayloadBuilder","hash","block","recoverState","getDeclaredCandidateRanges","address","intent","Promise","resolve","results","get","getDeclaredCandidatesForBlock","spanAsync","findAllContaining","candidates","validCandidates","filterToValidStake","isStakedForBlock","includes","requiredMinimumStake","candidatesWithStake","all","map","candidate","stake","activeStake","activeByAddressStaked","set","ttl","filter","persistState","current","state","serialize","payload","schema","ChainIndexingServiceStateSchema","fields","endBlockHash","build","insert","currentBlock","asOptionalBlockBoundWitness","currentBlockNum","opts","DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS","predicate","p","asOptionalChainIndexingServiceStateWithStorageMeta","findFirstMatching","isChainIndexingServiceState","indexed","indexedBlock","asOptionalBlockBoundWitnessWithStorageMeta","indexedBlockNum","data","_hash","open","displayProgress","isLocked","runExclusive","currentHead","currentHeadHash","result","analyzeChain","ChainStakeIntentAnalyzer","signedDeclarations","filterAs","find","isChainSummaryStakeIntent","intents","asOptionalChainStakeIntent","currentHeadBlockNum","logger","info","signedDeclaration","exp","nbf","start","stop","asAddress","from","Base","toAddress","StakedXyoChain__factory","StakedXyoChainFactory","getAddress","EvmChainService","Base","_contract","params","contract","id","runner","create","logger","traceProvider","meterProvider","contractAddress","getAddress","StakedXyoChainFactory","connect","active","activeByAddressStaked","address","activeByStaker","addStake","staked","amount","result","wait","chainId","toAddress","forkedAtBlockNumber","forkedAtHash","forkedChainId","minWithdrawalBlocks","pending","pendingByStaker","staker","removeStake","slot","rewardsContract","stakingTokenAddress","withdrawStake","withdrawn","withdrawnByStaker","assertEx","BaseEmitter","isDefined","isNull","PayloadBuilder","asBlockBoundWitness","asOptionalBlockBoundWitness","isBlockBoundWitness","LRUCache","XyoChainBlockNumberIterator","BaseEmitter","_blocksByBlockNumber","LRUCache","max","_chainArchivist","_chainInformation","_head","params","chainArchivist","archivist","head","id","chain","chainIdentification","create","Promise","resolve","get","block","assertEx","cached","startingBlock","currentBlockHash","PayloadBuilder","hash","currentBlock","at","isDefined","asBlockBoundWitness","_hash","isBlockBoundWitness","set","previous","isNull","Error","next","nextBlockNumber","undefined","count","results","length","push","nextBlock","asOptionalBlockBoundWitness","updateHead","emit","blocks"]}
@@ -2,7 +2,7 @@ import { Address } from '@xylabs/hex';
2
2
  import { ArchivistInstance, ReadArchivist } from '@xyo-network/archivist-model';
3
3
  import { BlockRewardDiviner } from '@xyo-network/chain-modules';
4
4
  import { WithStorageMeta } from '@xyo-network/payload-model';
5
- import { BlockBoundWitness, BlockProducer, ChainStakeIntent, HydratedBlock, PendingTransactionsService, StakeIntentService, Transfer } from '@xyo-network/xl1-protocol';
5
+ import { AccountBalanceService, BlockBoundWitness, BlockProducer, ChainStakeIntent, HydratedBlock, PendingTransactionsService, StakeIntentService, Transfer } from '@xyo-network/xl1-protocol';
6
6
  import { BaseService } from '../BaseService.ts';
7
7
  import { XyoValidatorParams } from '../ChainValidator/index.ts';
8
8
  /**
@@ -16,6 +16,7 @@ export declare const XYO_PRODUCER_RESTAKE_DURATION = 10000;
16
16
  */
17
17
  export declare const XYO_PRODUCER_RESTAKE_WINDOW = 500n;
18
18
  export interface XyoBlockProducerParams extends XyoValidatorParams {
19
+ accountBalanceService?: AccountBalanceService;
19
20
  pendingTransactionsArchivist?: ReadArchivist;
20
21
  pendingTransactionsService?: PendingTransactionsService;
21
22
  rejectedTransactionsArchivist?: ArchivistInstance;
@@ -27,6 +28,7 @@ export declare class XyoBlockProducer extends BaseService<XyoBlockProducerParams
27
28
  static get DefaultBlockSize(): number;
28
29
  get address(): Lowercase<string>;
29
30
  protected get account(): import("@xyo-network/account-model").AccountInstance;
31
+ protected get accountBalanceService(): AccountBalanceService;
30
32
  protected get chainFinalizedArchivist(): ReadArchivist<import("@xyo-network/payload-model").Payload, Lowercase<string>>;
31
33
  protected get chainInfo(): import("@xyo-network/xl1-protocol").ChainInformation;
32
34
  protected get electionService(): import("@xyo-network/xl1-protocol").ElectionService;
@@ -1 +1 @@
1
- {"version":3,"file":"XyoBlockProducer.d.ts","sourceRoot":"","sources":["../../../src/BlockProducer/XyoBlockProducer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAA;AAE5C,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AAC/E,OAAO,EACL,kBAAkB,EACnB,MAAM,4BAA4B,CAAA;AAGnC,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AAC5D,OAAO,EACqC,iBAAiB,EAAkC,aAAa,EAAE,gBAAgB,EAC5H,aAAa,EAAE,0BAA0B,EAAE,kBAAkB,EAAE,QAAQ,EACxE,MAAM,2BAA2B,CAAA;AAElC,OAAO,EAAE,WAAW,EAAoB,MAAM,mBAAmB,CAAA;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAG/D;;GAEG;AACH,eAAO,MAAM,kBAAkB,KAAK,CAAA;AAKpC,eAAO,MAAM,6BAA6B,QAAS,CAAA;AAEnD;;;GAGG;AACH,eAAO,MAAM,2BAA2B,OAAO,CAAA;AAE/C,MAAM,WAAW,sBAAuB,SAAQ,kBAAkB;IAChE,4BAA4B,CAAC,EAAE,aAAa,CAAA;IAC5C,0BAA0B,CAAC,EAAE,0BAA0B,CAAA;IACvD,6BAA6B,CAAC,EAAE,iBAAiB,CAAA;IACjD,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,kBAAkB,CAAC,EAAE,kBAAkB,CAAA;CACxC;AAED,qBACa,gBAAiB,SAAQ,WAAW,CAAC,sBAAsB,CAAE,YAAW,aAAa;IAChG,SAAS,CAAC,mBAAmB,EAAE,kBAAkB,GAAG,SAAS,CAAA;IAE7D,MAAM,KAAK,gBAAgB,IAAI,MAAM,CAEpC;IAED,IAAI,OAAO,sBAEV;IAED,SAAS,KAAK,OAAO,yDAEpB;IAED,SAAS,KAAK,uBAAuB,mFAEpC;IAED,SAAS,KAAK,SAAS,yDAEtB;IAED,SAAS,KAAK,eAAe,wDAE5B;IAED,SAAS,KAAK,mBAAmB;;;;;;;;wPAEhC;IAED,SAAS,KAAK,0BAA0B,+BAEvC;IAED,SAAS,KAAK,6BAA6B;;;;;;;;wPAE1C;IAED,SAAS,KAAK,aAAa,IAAI,OAAO,CAErC;IAED,SAAS,KAAK,aAAa,2DAE1B;IAED,SAAS,KAAK,kBAAkB,IAAI,kBAAkB,CAErD;IAED,SAAS,KAAK,0BAA0B,6EAEvC;IAEK,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,iBAAiB,CAAC,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;cAWxE,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IAoBpF;;;;OAIG;cACa,wBAAwB,CAAC,IAAI,EAAE,eAAe,CAAC,iBAAiB,CAAC,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;cAwBzG,qBAAqB,CAAC,IAAI,EAAE,eAAe,CAAC,iBAAiB,CAAC,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;CAoCpH"}
1
+ {"version":3,"file":"XyoBlockProducer.d.ts","sourceRoot":"","sources":["../../../src/BlockProducer/XyoBlockProducer.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,OAAO,EACR,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AAC/E,OAAO,EACL,kBAAkB,EACnB,MAAM,4BAA4B,CAAA;AAGnC,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AAC5D,OAAO,EACL,qBAAqB,EACqB,iBAAiB,EAAkC,aAAa,EAAE,gBAAgB,EAC5H,aAAa,EAAE,0BAA0B,EAAE,kBAAkB,EAAE,QAAQ,EACxE,MAAM,2BAA2B,CAAA;AAElC,OAAO,EAAE,WAAW,EAAoB,MAAM,mBAAmB,CAAA;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAG/D;;GAEG;AACH,eAAO,MAAM,kBAAkB,KAAK,CAAA;AAKpC,eAAO,MAAM,6BAA6B,QAAS,CAAA;AAEnD;;;GAGG;AACH,eAAO,MAAM,2BAA2B,OAAO,CAAA;AAE/C,MAAM,WAAW,sBAAuB,SAAQ,kBAAkB;IAChE,qBAAqB,CAAC,EAAE,qBAAqB,CAAA;IAC7C,4BAA4B,CAAC,EAAE,aAAa,CAAA;IAC5C,0BAA0B,CAAC,EAAE,0BAA0B,CAAA;IACvD,6BAA6B,CAAC,EAAE,iBAAiB,CAAA;IACjD,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,kBAAkB,CAAC,EAAE,kBAAkB,CAAA;CACxC;AAED,qBACa,gBAAiB,SAAQ,WAAW,CAAC,sBAAsB,CAAE,YAAW,aAAa;IAChG,SAAS,CAAC,mBAAmB,EAAE,kBAAkB,GAAG,SAAS,CAAA;IAE7D,MAAM,KAAK,gBAAgB,IAAI,MAAM,CAEpC;IAED,IAAI,OAAO,sBAEV;IAED,SAAS,KAAK,OAAO,yDAEpB;IAED,SAAS,KAAK,qBAAqB,0BAElC;IAED,SAAS,KAAK,uBAAuB,mFAEpC;IAED,SAAS,KAAK,SAAS,yDAEtB;IAED,SAAS,KAAK,eAAe,wDAE5B;IAED,SAAS,KAAK,mBAAmB;;;;;;;;wPAEhC;IAED,SAAS,KAAK,0BAA0B,+BAEvC;IAED,SAAS,KAAK,6BAA6B;;;;;;;;wPAE1C;IAED,SAAS,KAAK,aAAa,IAAI,OAAO,CAErC;IAED,SAAS,KAAK,aAAa,2DAE1B;IAED,SAAS,KAAK,kBAAkB,IAAI,kBAAkB,CAErD;IAED,SAAS,KAAK,0BAA0B,6EAEvC;IAEK,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,iBAAiB,CAAC,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;cAWxE,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IAoBpF;;;;OAIG;cACa,wBAAwB,CAAC,IAAI,EAAE,eAAe,CAAC,iBAAiB,CAAC,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;cAwBzG,qBAAqB,CAAC,IAAI,EAAE,eAAe,CAAC,iBAAiB,CAAC,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;CAiDpH"}
@@ -1,4 +1,4 @@
1
1
  import { type Address } from '@xylabs/hex';
2
- import { type HydratedTransaction, type Transfer } from '@xyo-network/xl1-protocol';
2
+ import type { HydratedTransaction, Transfer } from '@xyo-network/xl1-protocol';
3
3
  export declare function generateTransactionTransfers(address: Address, transactions: HydratedTransaction[]): Promise<Transfer[]>;
4
4
  //# sourceMappingURL=generateTransactionTransfers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generateTransactionTransfers.d.ts","sourceRoot":"","sources":["../../../src/BlockProducer/generateTransactionTransfers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAiB,MAAM,aAAa,CAAA;AAEzD,OAAO,EACL,KAAK,mBAAmB,EAAE,KAAK,QAAQ,EACxC,MAAM,2BAA2B,CAAA;AAElC,wBAAsB,4BAA4B,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CA0B7H"}
1
+ {"version":3,"file":"generateTransactionTransfers.d.ts","sourceRoot":"","sources":["../../../src/BlockProducer/generateTransactionTransfers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,OAAO,EAAiB,MAAM,aAAa,CAAA;AAGzD,OAAO,KAAK,EACV,mBAAmB,EACnB,QAAQ,EACT,MAAM,2BAA2B,CAAA;AAQlC,wBAAsB,4BAA4B,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAsC7H"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "http://json.schemastore.org/package.json",
3
3
  "name": "@xyo-network/chain-services",
4
- "version": "1.4.0",
4
+ "version": "1.4.2",
5
5
  "description": "XYO Layer One SDK Services",
6
6
  "homepage": "https://xylabs.com",
7
7
  "bugs": {
@@ -51,17 +51,17 @@
51
51
  "@xyo-network/boundwitness-model": "^3.16.1",
52
52
  "@xyo-network/boundwitness-validator": "^3.16.1",
53
53
  "@xyo-network/boundwitness-wrapper": "^3.16.1",
54
- "@xyo-network/chain-analyze": "^1.4.0",
55
- "@xyo-network/chain-modules": "^1.4.0",
56
- "@xyo-network/chain-protocol": "^1.4.0",
57
- "@xyo-network/chain-utils": "^1.4.0",
58
- "@xyo-network/chain-validation": "^1.4.0",
59
- "@xyo-network/chain-wrappers": "^1.4.0",
54
+ "@xyo-network/chain-analyze": "^1.4.2",
55
+ "@xyo-network/chain-modules": "^1.4.2",
56
+ "@xyo-network/chain-protocol": "^1.4.2",
57
+ "@xyo-network/chain-utils": "^1.4.2",
58
+ "@xyo-network/chain-validation": "^1.4.2",
59
+ "@xyo-network/chain-wrappers": "^1.4.2",
60
60
  "@xyo-network/payload-builder": "^3.16.1",
61
61
  "@xyo-network/payload-model": "^3.16.1",
62
62
  "@xyo-network/typechain": "^3.5.2",
63
- "@xyo-network/xl1-protocol": "^1.3.29",
64
- "@xyo-network/xl1-protocol-sdk": "^1.4.0",
63
+ "@xyo-network/xl1-protocol": "^1.3.31",
64
+ "@xyo-network/xl1-protocol-sdk": "^1.4.2",
65
65
  "async-mutex": "^0.5.0",
66
66
  "ethers": "6.14.1",
67
67
  "lru-cache": "^11.1.0",
@@ -75,9 +75,9 @@
75
75
  "@xylabs/vitest-extended": "^4.9.18",
76
76
  "@xyo-network/account": "^3.16.1",
77
77
  "@xyo-network/account-model": "^3.16.1",
78
- "@xyo-network/chain-validation": "^1.4.0",
78
+ "@xyo-network/chain-validation": "^1.4.2",
79
79
  "@xyo-network/wallet": "^3.16.1",
80
- "knip": "^5.56.0",
80
+ "knip": "^5.57.0",
81
81
  "typescript": "^5.8.3",
82
82
  "vitest": "^3.1.4",
83
83
  "vitest-mock-extended": "^3.1.0"
@@ -1,5 +1,8 @@
1
1
  import { assertEx } from '@xylabs/assert'
2
- import { Address, toHex } from '@xylabs/hex'
2
+ import { exists } from '@xylabs/exists'
3
+ import {
4
+ Address, hexToBigInt, toHex,
5
+ } from '@xylabs/hex'
3
6
  import { isUndefined } from '@xylabs/typeof'
4
7
  import { ArchivistInstance, ReadArchivist } from '@xyo-network/archivist-model'
5
8
  import {
@@ -9,6 +12,7 @@ import { buildBlock } from '@xyo-network/chain-protocol'
9
12
  import { PayloadBuilder } from '@xyo-network/payload-builder'
10
13
  import { WithStorageMeta } from '@xyo-network/payload-model'
11
14
  import {
15
+ AccountBalanceService,
12
16
  AllowedBlockPayload, asBlockBoundWitness, BlockBoundWitness, BlockNumber, BlockNumberSchema, BlockProducer, ChainStakeIntent, ChainStakeIntentSchema,
13
17
  HydratedBlock, PendingTransactionsService, StakeIntentService, Transfer,
14
18
  } from '@xyo-network/xl1-protocol'
@@ -34,6 +38,7 @@ export const XYO_PRODUCER_RESTAKE_DURATION = 10_000
34
38
  export const XYO_PRODUCER_RESTAKE_WINDOW = 500n
35
39
 
36
40
  export interface XyoBlockProducerParams extends XyoValidatorParams {
41
+ accountBalanceService?: AccountBalanceService
37
42
  pendingTransactionsArchivist?: ReadArchivist
38
43
  pendingTransactionsService?: PendingTransactionsService
39
44
  rejectedTransactionsArchivist?: ArchivistInstance
@@ -57,6 +62,10 @@ export class XyoBlockProducer extends BaseService<XyoBlockProducerParams> implem
57
62
  return assertEx(this.params.account, () => 'account is required')
58
63
  }
59
64
 
65
+ protected get accountBalanceService() {
66
+ return assertEx(this.params.accountBalanceService, () => 'accountBalanceService is required')
67
+ }
68
+
60
69
  protected get chainFinalizedArchivist() {
61
70
  return assertEx(this.params.chainFinalizedArchivist, () => 'chainFinalizedArchivist is required')
62
71
  }
@@ -116,7 +125,7 @@ export class XyoBlockProducer extends BaseService<XyoBlockProducerParams> implem
116
125
  blockRewardService: this.rewardService,
117
126
  config: {
118
127
  rewardAddress: this.rewardAddress,
119
- rewardPercentageRatio: 0,
128
+ rewardPercentageRatio: 50,
120
129
  schema: FixedPercentageBlockRewardDivinerConfigSchema,
121
130
  },
122
131
  })
@@ -178,10 +187,23 @@ export class XyoBlockProducer extends BaseService<XyoBlockProducerParams> implem
178
187
  if (rewardTransferPayload) blockPayloads.push(rewardTransferPayload)
179
188
 
180
189
  const transactionTransfers = await generateTransactionTransfers(this.address, nextBlockTransactions)
181
- blockPayloads.push(...transactionTransfers)
190
+
191
+ const fundedTransfers: Transfer[] = []
192
+
193
+ const fundedNextBlockTransactions = nextBlockTransactions.map((tx) => {
194
+ const transfer: Transfer | undefined = transactionTransfers.find(txTransfer => txTransfer.from === tx[0].from)
195
+ if (!transfer) return
196
+ const totalTransferCost = Object.values(transfer?.transfers).reduce((acc, t) => acc + hexToBigInt(t), 0n)
197
+ if (hexToBigInt(this.accountBalanceService.getBalance(this.address)) >= totalTransferCost) {
198
+ fundedTransfers.push(transfer)
199
+ return tx
200
+ }
201
+ }).filter(exists)
202
+
203
+ blockPayloads.push(...fundedTransfers)
182
204
 
183
205
  // Build the block
184
- const block = await buildBlock(head, nextBlockTransactions, blockPayloads, [this.account])
206
+ const block = await buildBlock(head, fundedNextBlockTransactions, blockPayloads, [this.account])
185
207
  console.log('buildBlock', block)
186
208
  const errors = await this.validateHydratedBlockState(block, this.chainInfo.id, this.chainFinalizedArchivist)
187
209
  if (errors.length > 0) {
@@ -1,33 +1,54 @@
1
+ import { assertEx } from '@xylabs/assert'
1
2
  import { type Address, hexFromBigInt } from '@xylabs/hex'
3
+ import { XYO_ZERO_ADDRESS } from '@xyo-network/chain-utils'
2
4
  import { HydratedTransactionWrapper } from '@xyo-network/chain-wrappers'
5
+ import type {
6
+ HydratedTransaction,
7
+ Transfer,
8
+ } from '@xyo-network/xl1-protocol'
3
9
  import {
4
- type HydratedTransaction, type Transfer, TransferSchema,
10
+ MicroXL1,
11
+ mXL1ToXL1, TransferSchema,
12
+ XL1,
5
13
  } from '@xyo-network/xl1-protocol'
14
+ import { transactionRequiredGas } from '@xyo-network/xl1-protocol-sdk'
6
15
 
7
16
  export async function generateTransactionTransfers(address: Address, transactions: HydratedTransaction[]): Promise<Transfer[]> {
8
17
  const txs = await Promise.all(transactions.map(tx => HydratedTransactionWrapper.parse(tx)))
9
18
 
10
19
  // merge transactions with the same from address
11
- const txCosts: [Address, bigint][] = []
20
+ const txBaseFeeCosts: Record<Address, XL1> = {}
12
21
  for (const tx of txs) {
13
- const existingItem = txCosts.find(([addr]) => addr === tx.boundWitness.from)
14
- if (existingItem) {
15
- existingItem[1] += tx.fees.base
16
- } else {
17
- txCosts.push([tx.boundWitness.from, tx.fees.base])
18
- }
22
+ txBaseFeeCosts[tx.boundWitness.from] = XL1((txBaseFeeCosts[tx.boundWitness.from] ?? 0n) + mXL1ToXL1(tx.fees.base))
23
+ }
24
+
25
+ const txGasCosts: Record<Address, XL1> = {}
26
+ for (const tx of txs) {
27
+ const requiredGas = transactionRequiredGas(tx.data)
28
+ const totalGasCostInMicroXL1 = MicroXL1(requiredGas * tx.fees.gasPrice)
29
+ txGasCosts[tx.boundWitness.from] = XL1((txBaseFeeCosts[tx.boundWitness.from] ?? 0n) + mXL1ToXL1(totalGasCostInMicroXL1))
19
30
  }
20
31
 
21
- // generate actual Transfer Payloads
22
- const payloads = txCosts.map(([from, amount]) => {
32
+ // generate actual Transfer Payloads & burn the base fee
33
+ const payloads = (Object.entries(txBaseFeeCosts) as [Address, XL1][]).map(([from, amount]) => {
23
34
  const payload: Transfer = {
24
35
  schema: TransferSchema,
25
36
  epoch: Date.now(),
26
37
  from,
27
- // TODO: add function to Wrapper to calculate entire cost of transaction
28
- transfers: { [address]: hexFromBigInt(amount) },
38
+ transfers: {
39
+ // burn the base fee
40
+ [XYO_ZERO_ADDRESS]: hexFromBigInt(amount),
41
+ },
29
42
  }
30
43
  return payload
31
44
  })
45
+
46
+ // transfer gas cost to producer
47
+ for (const [from, amount] of Object.entries(txGasCosts)) {
48
+ // every gas from should also be a base fee from
49
+ const fromPayload = assertEx(payloads.find(p => p.from === from), () => 'from payload not found')
50
+ fromPayload.transfers[address] = hexFromBigInt(amount)
51
+ }
52
+
32
53
  return payloads
33
54
  }