@xyo-network/chain-services 1.19.14 → 1.19.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/neutral/Election/BaseElectionService.d.ts +1 -1
  2. package/dist/neutral/Election/BaseElectionService.d.ts.map +1 -1
  3. package/dist/neutral/NetworkStakeStepReward/BaseNetworkStakeStepRewardService.d.ts +1 -1
  4. package/dist/neutral/NetworkStakeStepReward/BaseNetworkStakeStepRewardService.d.ts.map +1 -1
  5. package/dist/neutral/StepStake/BaseStepStakeService.d.ts +1 -1
  6. package/dist/neutral/StepStake/BaseStepStakeService.d.ts.map +1 -1
  7. package/dist/neutral/index.d.ts +0 -2
  8. package/dist/neutral/index.d.ts.map +1 -1
  9. package/dist/neutral/index.mjs +32 -578
  10. package/dist/neutral/index.mjs.map +1 -1
  11. package/dist/neutral/simple/block/runner/SimpleBlockRunner.d.ts +8 -6
  12. package/dist/neutral/simple/block/runner/SimpleBlockRunner.d.ts.map +1 -1
  13. package/package.json +31 -28
  14. package/src/Election/BaseElectionService.ts +1 -1
  15. package/src/NetworkStakeStepReward/BaseNetworkStakeStepRewardService.ts +1 -1
  16. package/src/StepStake/BaseStepStakeService.ts +1 -1
  17. package/src/index.ts +0 -2
  18. package/src/simple/block/runner/SimpleBlockRunner.ts +12 -13
  19. package/src/simple/block/runner/generateTransactionFeeTransfers.ts +1 -1
  20. package/dist/neutral/PendingTransactions/BasePendingTransactions.d.ts +0 -64
  21. package/dist/neutral/PendingTransactions/BasePendingTransactions.d.ts.map +0 -1
  22. package/dist/neutral/PendingTransactions/bundledPayloadToHydratedTransaction.d.ts +0 -4
  23. package/dist/neutral/PendingTransactions/bundledPayloadToHydratedTransaction.d.ts.map +0 -1
  24. package/dist/neutral/PendingTransactions/hydratedTransactionToPayloadBundle.d.ts +0 -4
  25. package/dist/neutral/PendingTransactions/hydratedTransactionToPayloadBundle.d.ts.map +0 -1
  26. package/dist/neutral/PendingTransactions/index.d.ts +0 -2
  27. package/dist/neutral/PendingTransactions/index.d.ts.map +0 -1
  28. package/dist/neutral/StakeIntent/XyoStakeIntentService.d.ts +0 -47
  29. package/dist/neutral/StakeIntent/XyoStakeIntentService.d.ts.map +0 -1
  30. package/dist/neutral/StakeIntent/index.d.ts +0 -3
  31. package/dist/neutral/StakeIntent/index.d.ts.map +0 -1
  32. package/dist/neutral/StakeIntent/lib/getBlockSignedStakeDeclarations.d.ts +0 -4
  33. package/dist/neutral/StakeIntent/lib/getBlockSignedStakeDeclarations.d.ts.map +0 -1
  34. package/dist/neutral/StakeIntent/lib/index.d.ts +0 -2
  35. package/dist/neutral/StakeIntent/lib/index.d.ts.map +0 -1
  36. package/src/PendingTransactions/BasePendingTransactions.ts +0 -382
  37. package/src/PendingTransactions/bundledPayloadToHydratedTransaction.ts +0 -14
  38. package/src/PendingTransactions/hydratedTransactionToPayloadBundle.ts +0 -18
  39. package/src/PendingTransactions/index.ts +0 -1
  40. package/src/StakeIntent/XyoStakeIntentService.ts +0 -259
  41. package/src/StakeIntent/index.ts +0 -2
  42. package/src/StakeIntent/lib/getBlockSignedStakeDeclarations.ts +0 -47
  43. package/src/StakeIntent/lib/index.ts +0 -1
@@ -3,13 +3,13 @@ import {
3
3
  } from '@xylabs/sdk-js'
4
4
  import { AccountInstance } from '@xyo-network/account-model'
5
5
  import { MemoryArchivist } from '@xyo-network/archivist-memory'
6
- import { ArchivistInstance } from '@xyo-network/archivist-model'
7
6
  import {
8
7
  BlockRewardDiviner, FixedPercentageBlockRewardDiviner, FixedPercentageBlockRewardDivinerConfigSchema,
9
8
  } from '@xyo-network/chain-modules'
10
9
  import { buildNextBlock } from '@xyo-network/chain-protocol'
11
- import { PayloadBuilder } from '@xyo-network/payload-builder'
12
- import { WithHashMeta } from '@xyo-network/payload-model'
10
+ import {
11
+ ArchivistInstance, PayloadBuilder, WithHashMeta,
12
+ } from '@xyo-network/sdk-js'
13
13
  import {
14
14
  AbstractCreatableProvider, AccountBalanceViewer, AccountBalanceViewerMoniker, AllowedBlockPayload, asBlockBoundWitness, AttoXL1, BlockBoundWitness,
15
15
  BlockNumberPayload, BlockNumberSchema, BlockRewardViewer, BlockRewardViewerMoniker, BlockRunner, BlockRunnerMoniker, BlockValidationViewer,
@@ -39,6 +39,8 @@ export const XYO_PRODUCER_REDECLARATION_WINDOW = 500
39
39
 
40
40
  export interface SimpleBlockRunnerParams extends CreatableProviderParams {
41
41
  account: AccountInstance
42
+ disableIntentRedeclaration?: boolean
43
+ heartbeatInterval?: number
42
44
  rejectedTransactionsArchivist?: ArchivistInstance
43
45
  rewardAddress: Address
44
46
  validateHydratedBlockState?: HydratedBlockStateValidationFunction
@@ -121,9 +123,9 @@ export class SimpleBlockRunner extends AbstractCreatableProvider<SimpleBlockRunn
121
123
  return this._chainId
122
124
  }
123
125
 
124
- // protected get electionService() {
125
- // return assertEx(this.params.electionService, () => 'electionService is required')
126
- // }
126
+ protected get heartbeatInterval() {
127
+ return this.params.heartbeatInterval ?? 3_600_000
128
+ }
127
129
 
128
130
  protected get mempoolRunner() {
129
131
  return this._mempoolRunner!
@@ -167,7 +169,7 @@ export class SimpleBlockRunner extends AbstractCreatableProvider<SimpleBlockRunn
167
169
  this._chainId = this.context.config.chain.id
168
170
  this._mempoolRunner = await this.locateAndCreate<MempoolRunner>(MempoolRunnerMoniker)
169
171
  this._mempoolViewer = await this.locateAndCreate<MempoolViewer>(MempoolViewerMoniker)
170
- this._rewardAddress = this.params.rewardAddress ?? this.context.config.actors.producer.rewardAddress
172
+ this._rewardAddress = this.params.rewardAddress
171
173
  this._timeSyncViewer = await this.locateAndCreate<TimeSyncViewer>(TimeSyncViewerMoniker)
172
174
  }
173
175
 
@@ -222,7 +224,7 @@ export class SimpleBlockRunner extends AbstractCreatableProvider<SimpleBlockRunn
222
224
  protected getProducerRedeclaration(head: WithHashMeta<BlockBoundWitness>): Promisable<ChainStakeIntent | undefined> {
223
225
  // TODO: Do not redeclare on every block
224
226
  // Decide if we should redeclare intent
225
- if (this.params.context.config.actors?.producer?.disableIntentRedeclaration) return
227
+ if (this.params.disableIntentRedeclaration) return
226
228
  // Decide if we need to redeclare intent
227
229
  // const ranges = await this.stakeIntentService.getDeclaredCandidateRanges(this.address, 'producer')
228
230
  // TODO: This doesn't handle the case where the producer had declared a range for the future
@@ -350,11 +352,8 @@ export class SimpleBlockRunner extends AbstractCreatableProvider<SimpleBlockRunn
350
352
  */
351
353
  private heartbeatRequired(head: WithHashMeta<BlockBoundWitness>): boolean {
352
354
  const epoch = head.$epoch
353
- if (isDefined(epoch)) {
354
- const { heartbeatInterval } = assertEx(this.params.context.config.actors?.producer)
355
- if (Date.now() - epoch > heartbeatInterval) {
356
- return true
357
- }
355
+ if (isDefined(epoch) && Date.now() - epoch > this.heartbeatInterval) {
356
+ return true
358
357
  }
359
358
  return false
360
359
  }
@@ -1,6 +1,6 @@
1
1
  import { type Address, hexFromBigInt } from '@xylabs/sdk-js'
2
2
  import { assertEx } from '@xylabs/sdk-js'
3
- import { PayloadBuilder } from '@xyo-network/payload-builder'
3
+ import { PayloadBuilder } from '@xyo-network/sdk-js'
4
4
  import type {
5
5
  SignedHydratedTransaction,
6
6
  Transfer,
@@ -1,64 +0,0 @@
1
- import { ArchivistInstance } from '@xyo-network/archivist-model';
2
- import { AbstractCreatableProvider, ChainId, HydratedTransactionValidationFunction, MempoolViewer, PendingBlocksOptions, PendingTransactionsOptions, SignedHydratedBlockWithHashMeta, SignedHydratedTransactionWithStorageMeta } from '@xyo-network/xl1-sdk';
3
- import { BaseServiceParams } from '../model/index.ts';
4
- export interface BasePendingTransactionsServiceParams extends BaseServiceParams {
5
- additionalPendingTransactionValidators?: HydratedTransactionValidationFunction[];
6
- chainArchivist: ArchivistInstance;
7
- chainId: ChainId;
8
- pendingBundledTransactionsArchivist: ArchivistInstance;
9
- rejectedTransactionsArchivist: ArchivistInstance;
10
- }
11
- export declare class BasePendingTransactionsService extends AbstractCreatableProvider<BasePendingTransactionsServiceParams> implements MempoolViewer {
12
- static readonly defaultMoniker: "MempoolViewer";
13
- static readonly dependencies: never[];
14
- static readonly monikers: "MempoolViewer"[];
15
- private static readonly MutexPriority;
16
- moniker: "MempoolViewer";
17
- /**
18
- * A mutex to ensure that the counting the number of pending transactions is
19
- * not called concurrently
20
- */
21
- private _countPendingTransactionsMutex;
22
- /**
23
- * A local Archivist optimized for fast retrieval that stores only validated
24
- * pending transactions
25
- */
26
- private _curatedPendingBundledTransactionsArchivist;
27
- /**
28
- * The last count of total pending transactions
29
- */
30
- private _pendingTransactionsCount;
31
- /**
32
- * A set of transaction hashes that are pending removal from the
33
- * curated pending transactions archivist. This is used to track
34
- * which transactions need to be removed from the archivist.
35
- */
36
- private _removablePendingTransactionHashes;
37
- /**
38
- * A mutex to ensure that the curated pending transactions archivist is
39
- * updated in a thread-safe manner
40
- */
41
- private _updateCuratedPendingTransactionsArchivistMutex;
42
- private get additionalPendingTransactionValidators();
43
- private get chainArchivist();
44
- private get pendingBundledTransactionsArchivist();
45
- private get pendingBundledTransactionsLocalArchivist();
46
- private get pendingTransactionsCount();
47
- private get rejectedTransactionsArchivist();
48
- createHandler(): Promise<void>;
49
- pendingBlocks(_options?: PendingBlocksOptions): Promise<SignedHydratedBlockWithHashMeta[]>;
50
- pendingTransactions({ limit }?: PendingTransactionsOptions): Promise<SignedHydratedTransactionWithStorageMeta[]>;
51
- private cleanupWorker;
52
- private countPendingTransactions;
53
- private filterAlreadyFinalizedTransactions;
54
- private insertNewTransactions;
55
- /**
56
- * Marks any included transactions in the provided payloads for removal preventing them
57
- * from being included in the curated pending transactions archivist and from being offered
58
- * during the next retrieval of pending transactions.
59
- * @param payloads An array of payloads that may contain transactions.
60
- */
61
- private markAnyIncludedTransactionsForRemoval;
62
- private pruneCuratedPendingTransactionsArchivist;
63
- }
64
- //# sourceMappingURL=BasePendingTransactions.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"BasePendingTransactions.d.ts","sourceRoot":"","sources":["../../../src/PendingTransactions/BasePendingTransactions.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAA;AAIhE,OAAO,EACL,yBAAyB,EAC0B,OAAO,EACrC,qCAAqC,EAC1D,aAAa,EAAwB,oBAAoB,EAAE,0BAA0B,EACrF,+BAA+B,EAE/B,wCAAwC,EAGzC,MAAM,sBAAsB,CAAA;AAG7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAIrD,MAAM,WAAW,oCAAqC,SAAQ,iBAAiB;IAC7E,sCAAsC,CAAC,EAAE,qCAAqC,EAAE,CAAA;IAChF,cAAc,EAAE,iBAAiB,CAAA;IACjC,OAAO,EAAE,OAAO,CAAA;IAChB,mCAAmC,EAAE,iBAAiB,CAAA;IACtD,6BAA6B,EAAE,iBAAiB,CAAA;CACjD;AAED,qBACa,8BAA+B,SAAQ,yBAAyB,CAAC,oCAAoC,CAAE,YAAW,aAAa;IAC1I,MAAM,CAAC,QAAQ,CAAC,cAAc,kBAAuB;IACrD,MAAM,CAAC,QAAQ,CAAC,YAAY,UAAK;IACjC,MAAM,CAAC,QAAQ,CAAC,QAAQ,oBAAyB;IAEjD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAa3B;IAED,OAAO,kBAAgD;IAEhE;;;OAGG;IACH,OAAO,CAAC,8BAA8B,CAAc;IAEpD;;;OAGG;IACH,OAAO,CAAC,2CAA2C,CAA6B;IAEhF;;OAEG;IACH,OAAO,CAAC,yBAAyB,CAAY;IAE7C;;;;OAIG;IACH,OAAO,CAAC,kCAAkC,CAAuB;IAEjE;;;OAGG;IACH,OAAO,CAAC,+CAA+C,CAAc;IAErE,OAAO,KAAK,sCAAsC,GAEjD;IAED,OAAO,KAAK,cAAc,GAEzB;IAED,OAAO,KAAK,mCAAmC,GAE9C;IAED,OAAO,KAAK,wCAAwC,GAEnD;IAED,OAAO,KAAK,wBAAwB,GAGnC;IAED,OAAO,KAAK,6BAA6B,GAExC;IAEc,aAAa;IAgC5B,aAAa,CAAC,QAAQ,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,+BAA+B,EAAE,CAAC;IAIpF,mBAAmB,CAAC,EAAE,KAAW,EAAE,GAAE,0BAA+B,GAAG,OAAO,CAAC,wCAAwC,EAAE,CAAC;YA8ElH,aAAa;YAOb,wBAAwB;YAQxB,kCAAkC;YAUlC,qBAAqB;IA0BnC;;;;;OAKG;IACH,OAAO,CAAC,qCAAqC;YAO/B,wCAAwC;CAsEvD"}
@@ -1,4 +0,0 @@
1
- import type { PayloadBundle, WithStorageMeta } from '@xyo-network/payload-model';
2
- import type { SignedHydratedTransactionWithHashMeta } from '@xyo-network/xl1-sdk';
3
- export declare const bundledPayloadToHydratedTransaction: (payload: WithStorageMeta<PayloadBundle>) => Promise<SignedHydratedTransactionWithHashMeta | undefined>;
4
- //# sourceMappingURL=bundledPayloadToHydratedTransaction.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bundledPayloadToHydratedTransaction.d.ts","sourceRoot":"","sources":["../../../src/PendingTransactions/bundledPayloadToHydratedTransaction.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AAChF,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,sBAAsB,CAAA;AAGjF,eAAO,MAAM,mCAAmC,GAC9C,SAAS,eAAe,CAAC,aAAa,CAAC,KACtC,OAAO,CAAC,qCAAqC,GAAG,SAAS,CAM3D,CAAA"}
@@ -1,4 +0,0 @@
1
- import type { PayloadBundle } from '@xyo-network/payload-model';
2
- import type { SignedHydratedTransactionWithHashMeta } from '@xyo-network/xl1-sdk';
3
- export declare const hydratedTransactionToPayloadBundle: (transaction: SignedHydratedTransactionWithHashMeta) => PayloadBundle;
4
- //# sourceMappingURL=hydratedTransactionToPayloadBundle.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hydratedTransactionToPayloadBundle.d.ts","sourceRoot":"","sources":["../../../src/PendingTransactions/hydratedTransactionToPayloadBundle.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAE/D,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,sBAAsB,CAAA;AAGjF,eAAO,MAAM,kCAAkC,GAAI,aAAa,qCAAqC,KAAG,aAGvG,CAAA"}
@@ -1,2 +0,0 @@
1
- export * from './BasePendingTransactions.ts';
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/PendingTransactions/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAA"}
@@ -1,47 +0,0 @@
1
- import { Address, Hash } from '@xylabs/sdk-js';
2
- import { ArchivistInstance } from '@xyo-network/archivist-model';
3
- import { IntervalMap } from '@xyo-network/chain-utils';
4
- import { Payload } from '@xyo-network/payload-model';
5
- import { AbstractCreatableProvider, BlockViewer, ChainStakeViewer, StakeIntentService } from '@xyo-network/xl1-sdk';
6
- import { type Intent } from '@xyo-network/xl1-sdk';
7
- import { Mutex } from 'async-mutex';
8
- import { LRUCache } from 'lru-cache';
9
- import { BaseServiceParams } from '../model/index.ts';
10
- export interface XyoStakeIntentServiceParams extends BaseServiceParams {
11
- blockViewer: BlockViewer;
12
- chainArchivist: ArchivistInstance;
13
- chainStakeViewer: ChainStakeViewer;
14
- stakeIntentStateArchivist: ArchivistInstance;
15
- }
16
- export declare class XyoStakeIntentService extends AbstractCreatableProvider<XyoStakeIntentServiceParams> implements StakeIntentService {
17
- static readonly defaultMoniker = "StakeIntent";
18
- static readonly dependencies: never[];
19
- static readonly monikers: string[];
20
- moniker: string;
21
- protected _lastIndexedBlockHash: Hash | undefined;
22
- protected _producers: IntervalMap<Address>;
23
- protected _stakeCache: LRUCache<Lowercase<string> & {
24
- readonly __hex: true;
25
- } & {
26
- readonly __address: true;
27
- }, bigint, unknown>;
28
- protected _updateMutex: Mutex;
29
- private _blockViewer?;
30
- private _chainStakeViewer?;
31
- protected get blockViewer(): BlockViewer<"BlockViewer">;
32
- protected get chainArchivist(): ArchivistInstance<import("@xyo-network/archivist-model").ArchivistParams<import("@xyo-network/module-model").AnyConfigSchema<import("@xyo-network/archivist-model").ArchivistConfig>>, import("@xyo-network/archivist-model").ArchivistModuleEventData, Payload>;
33
- protected get chainStakeViewer(): ChainStakeViewer;
34
- protected get stakeIntentStateArchivist(): ArchivistInstance<import("@xyo-network/archivist-model").ArchivistParams<import("@xyo-network/module-model").AnyConfigSchema<import("@xyo-network/archivist-model").ArchivistConfig>>, import("@xyo-network/archivist-model").ArchivistModuleEventData, Payload>;
35
- static paramsHandler(params: Partial<XyoStakeIntentServiceParams>): Promise<XyoStakeIntentServiceParams>;
36
- createHandler(): Promise<void>;
37
- getDeclaredCandidateRanges(address: Address, intent: Intent): Promise<Readonly<Readonly<[number, number]>[]>>;
38
- getDeclaredCandidatesForBlock(block: number, intent: Intent): Promise<Address[]>;
39
- getRequiredMinimumStakeForIntent(intent: Intent): bigint;
40
- isStakedForBlock(block: number, intent: Intent, address: Address): Promise<boolean>;
41
- startHandler(): Promise<void>;
42
- private filterToValidStake;
43
- private persistState;
44
- private recoverState;
45
- private updateIndex;
46
- }
47
- //# sourceMappingURL=XyoStakeIntentService.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"XyoStakeIntentService.d.ts","sourceRoot":"","sources":["../../../src/StakeIntent/XyoStakeIntentService.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EAAiC,IAAI,EAE7C,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,iBAAiB,EAAwB,MAAM,8BAA8B,CAAA;AAKtF,OAAO,EAEc,WAAW,EAE/B,MAAM,0BAA0B,CAAA;AAEjC,OAAO,EAAE,OAAO,EAAmB,MAAM,4BAA4B,CAAA;AACrE,OAAO,EACL,yBAAyB,EAEzB,WAAW,EAEiD,gBAAgB,EAK5E,kBAAkB,EAEnB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACwE,KAAK,MAAM,EACzF,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAEpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAErD,MAAM,WAAW,2BAA4B,SAAQ,iBAAiB;IACpE,WAAW,EAAE,WAAW,CAAA;IACxB,cAAc,EAAE,iBAAiB,CAAA;IACjC,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,yBAAyB,EAAE,iBAAiB,CAAA;CAC7C;AAWD,qBACa,qBAAsB,SAAQ,yBAAyB,CAAC,2BAA2B,CAAE,YAAW,kBAAkB;IAC7H,MAAM,CAAC,QAAQ,CAAC,cAAc,iBAAgB;IAC9C,MAAM,CAAC,QAAQ,CAAC,YAAY,UAAK;IACjC,MAAM,CAAC,QAAQ,CAAC,QAAQ,WAAyC;IACjE,OAAO,SAAgB;IAEvB,SAAS,CAAC,qBAAqB,EAAE,IAAI,GAAG,SAAS,CAAY;IAS7D,SAAS,CAAC,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,CAAoB;IAC9D,SAAS,CAAC,WAAW;;;;wBAAkE;IACvF,SAAS,CAAC,YAAY,QAAc;IAEpC,OAAO,CAAC,YAAY,CAAC,CAAa;IAClC,OAAO,CAAC,iBAAiB,CAAC,CAAkB;IAE5C,SAAS,KAAK,WAAW,+BAExB;IAED,SAAS,KAAK,cAAc,qQAE3B;IAED,SAAS,KAAK,gBAAgB,qBAE7B;IAED,SAAS,KAAK,yBAAyB,qQAEtC;WAEqB,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,2BAA2B,CAAC,GAAG,OAAO,CAAC,2BAA2B,CAAC;IAQxG,aAAa;IAQtB,0BAA0B,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;IAO7G,6BAA6B,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAWtF,gCAAgC,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IASlD,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAK1E,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;YAI9B,kBAAkB;YAkClB,YAAY;YAQZ,YAAY;YAiCZ,WAAW;CAuC1B"}
@@ -1,3 +0,0 @@
1
- export * from './lib/index.ts';
2
- export * from './XyoStakeIntentService.ts';
3
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/StakeIntent/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,4BAA4B,CAAA"}
@@ -1,4 +0,0 @@
1
- import type { ArchivistInstance } from '@xyo-network/archivist-model';
2
- import type { BlockBoundWitness, ChainStakeIntent, Intent } from '@xyo-network/xl1-sdk';
3
- export declare const getBlockSignedStakeDeclarations: (block: BlockBoundWitness, archivist: ArchivistInstance, intent: Intent) => Promise<ChainStakeIntent[]>;
4
- //# sourceMappingURL=getBlockSignedStakeDeclarations.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getBlockSignedStakeDeclarations.d.ts","sourceRoot":"","sources":["../../../../src/StakeIntent/lib/getBlockSignedStakeDeclarations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAA;AAKrE,OAAO,KAAK,EACV,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,EAC5C,MAAM,sBAAsB,CAAA;AAG7B,eAAO,MAAM,+BAA+B,GAAU,OAAO,iBAAiB,EAAE,WAAW,iBAAiB,EAAE,QAAQ,MAAM,KAAG,OAAO,CAAC,gBAAgB,EAAE,CAyBxJ,CAAA"}
@@ -1,2 +0,0 @@
1
- export * from './getBlockSignedStakeDeclarations.ts';
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/StakeIntent/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,sCAAsC,CAAA"}
@@ -1,382 +0,0 @@
1
- import { ValueType } from '@opentelemetry/api'
2
- import {
3
- assertEx,
4
- exists,
5
- filterAs, filterAsync, forget, Hash,
6
- isDefined, isUndefined,
7
- } from '@xylabs/sdk-js'
8
- import { MemoryArchivist } from '@xyo-network/archivist-memory'
9
- import { ArchivistInstance } from '@xyo-network/archivist-model'
10
- import {
11
- Payload, PayloadBundle, Sequence, WithStorageMeta,
12
- } from '@xyo-network/payload-model'
13
- import {
14
- AbstractCreatableProvider,
15
- asBlockBoundWitnessWithHashMeta, asXL1BlockNumber, ChainId, creatableProvider,
16
- findMostRecentBlock, HydratedTransactionValidationFunction, isTransactionBoundWitnessWithStorageMeta,
17
- MempoolViewer, MempoolViewerMoniker, PendingBlocksOptions, PendingTransactionsOptions,
18
- SignedHydratedBlockWithHashMeta,
19
- SignedHydratedTransactionWithHashMeta,
20
- SignedHydratedTransactionWithStorageMeta,
21
- TransactionJsonSchemaValidator, validateTransaction,
22
- XL1BlockNumber,
23
- } from '@xyo-network/xl1-sdk'
24
- import { Mutex } from 'async-mutex'
25
-
26
- import { BaseServiceParams } from '../model/index.ts'
27
- import { bundledPayloadToHydratedTransaction } from './bundledPayloadToHydratedTransaction.ts'
28
- import { hydratedTransactionToPayloadBundle } from './hydratedTransactionToPayloadBundle.ts'
29
-
30
- export interface BasePendingTransactionsServiceParams extends BaseServiceParams {
31
- additionalPendingTransactionValidators?: HydratedTransactionValidationFunction[]
32
- chainArchivist: ArchivistInstance
33
- chainId: ChainId
34
- pendingBundledTransactionsArchivist: ArchivistInstance
35
- rejectedTransactionsArchivist: ArchivistInstance
36
- }
37
-
38
- @creatableProvider()
39
- export class BasePendingTransactionsService extends AbstractCreatableProvider<BasePendingTransactionsServiceParams> implements MempoolViewer {
40
- static readonly defaultMoniker = MempoolViewerMoniker
41
- static readonly dependencies = []
42
- static readonly monikers = [MempoolViewerMoniker]
43
-
44
- private static readonly MutexPriority = {
45
- /**
46
- * Priority for inserting new transactions
47
- */
48
- InsertNewTransactions: 5,
49
- /**
50
- * Priority for reading pending transactions
51
- */
52
- ReadTransactions: 3,
53
- /**
54
- * Priority for removing finalized/expired/rejected transactions
55
- */
56
- PurgeTransactions: 1,
57
- } as const
58
-
59
- override moniker = BasePendingTransactionsService.defaultMoniker
60
-
61
- /**
62
- * A mutex to ensure that the counting the number of pending transactions is
63
- * not called concurrently
64
- */
65
- private _countPendingTransactionsMutex = new Mutex()
66
-
67
- /**
68
- * A local Archivist optimized for fast retrieval that stores only validated
69
- * pending transactions
70
- */
71
- private _curatedPendingBundledTransactionsArchivist: MemoryArchivist | undefined
72
-
73
- /**
74
- * The last count of total pending transactions
75
- */
76
- private _pendingTransactionsCount: number = 0
77
-
78
- /**
79
- * A set of transaction hashes that are pending removal from the
80
- * curated pending transactions archivist. This is used to track
81
- * which transactions need to be removed from the archivist.
82
- */
83
- private _removablePendingTransactionHashes: Set<Hash> = new Set()
84
-
85
- /**
86
- * A mutex to ensure that the curated pending transactions archivist is
87
- * updated in a thread-safe manner
88
- */
89
- private _updateCuratedPendingTransactionsArchivistMutex = new Mutex()
90
-
91
- private get additionalPendingTransactionValidators() {
92
- return this.params.additionalPendingTransactionValidators ?? []
93
- }
94
-
95
- private get chainArchivist() {
96
- return assertEx(this.params.chainArchivist, () => 'No completed blocks with data archivist')
97
- }
98
-
99
- private get pendingBundledTransactionsArchivist() {
100
- return assertEx(this.params.pendingBundledTransactionsArchivist, () => 'No pending bundled transactions archivist')
101
- }
102
-
103
- private get pendingBundledTransactionsLocalArchivist() {
104
- return assertEx(this._curatedPendingBundledTransactionsArchivist, () => 'No pending bundled transactions curated archivist')
105
- }
106
-
107
- private get pendingTransactionsCount() {
108
- forget(this.countPendingTransactions())
109
- return this._pendingTransactionsCount
110
- }
111
-
112
- private get rejectedTransactionsArchivist() {
113
- return assertEx(this.params.rejectedTransactionsArchivist, () => 'No rejected transactions archivist')
114
- }
115
-
116
- override async createHandler() {
117
- await super.createHandler()
118
- this._curatedPendingBundledTransactionsArchivist = await MemoryArchivist.create({ account: 'random' })
119
-
120
- // On new pending transactions, insert them into the curated archivist
121
- this.pendingBundledTransactionsArchivist.on('inserted', ({ payloads }) => {
122
- forget(this.insertNewTransactions(payloads as WithStorageMeta<PayloadBundle>[]))
123
- })
124
-
125
- // On new finalized blocks, remove the transactions from the curated archivist
126
- this.chainArchivist.on('inserted', ({ payloads }) => {
127
- this.markAnyIncludedTransactionsForRemoval(payloads)
128
- forget(this.cleanupWorker())
129
- })
130
-
131
- // On new rejected transactions, remove the transactions from the curated archivist
132
- this.rejectedTransactionsArchivist.on('inserted', ({ payloads }) => {
133
- this.markAnyIncludedTransactionsForRemoval(payloads)
134
- forget(this.cleanupWorker())
135
- })
136
-
137
- const pendingTransactionsCounter = this.meter?.createObservableUpDownCounter(
138
- 'xyo_pending_transactions_counter',
139
- {
140
- description: 'The current number of pending transactions', valueType: ValueType.INT, unit: '1',
141
- },
142
- )
143
- pendingTransactionsCounter?.addCallback((observer) => {
144
- observer.observe(this.pendingTransactionsCount)
145
- })
146
- }
147
-
148
- pendingBlocks(_options?: PendingBlocksOptions): Promise<SignedHydratedBlockWithHashMeta[]> {
149
- throw new Error('Method [pendingBlocks] not implemented.')
150
- }
151
-
152
- async pendingTransactions({ limit = 100 }: PendingTransactionsOptions = {}): Promise<SignedHydratedTransactionWithStorageMeta[]> {
153
- return await this.spanAsync('getPendingTransactions', async () => {
154
- // Acquires an exclusive mutex to ensure no race conditions while accessing pending transactions.
155
- return await this._updateCuratedPendingTransactionsArchivistMutex.runExclusive(async () => {
156
- // Find the supplied head
157
- let lastHead = (filterAs(await this.chainArchivist.next({ limit: 100 }), x => asBlockBoundWitnessWithHashMeta(x))).at(-1)
158
- if (isUndefined(lastHead)) return []
159
-
160
- await this.pruneCuratedPendingTransactionsArchivist(lastHead._hash)
161
-
162
- const foundPendingTransactions: SignedHydratedTransactionWithStorageMeta[] = []
163
- let cursor: Sequence | undefined
164
-
165
- // Continue fetching until the desired number of transactions is reached.
166
- while (foundPendingTransactions.length < limit) {
167
- // Fetch the next batch of payloads
168
- const pendingBundledTransactions = await this.pendingBundledTransactionsLocalArchivist.next({
169
- limit: 100,
170
- order: 'asc',
171
- cursor,
172
- }) as WithStorageMeta<PayloadBundle>[]
173
-
174
- // Exit if no more payloads are available.
175
- if (pendingBundledTransactions.length === 0) break
176
-
177
- // Update the cursor for the next iteration to fetch subsequent payloads.
178
- cursor = pendingBundledTransactions.at(-1)?._sequence
179
-
180
- // Keep only those payloads that are not marked for deletion.
181
- const undeletedTransactionBundles = pendingBundledTransactions.filter(tx =>
182
- !this._removablePendingTransactionHashes.has(tx.root))
183
-
184
- // Convert each undeleted payload bundle into a hydrated transaction.
185
- const transactions = (await Promise.all(
186
- undeletedTransactionBundles.map(p => bundledPayloadToHydratedTransaction(p)),
187
- )).filter(exists)
188
-
189
- // Filter transactions to only include those that are active for the next
190
- // potential block based on the last supplied head.
191
- const activeTransactions = transactions.filter(isTransactionActive(asXL1BlockNumber(lastHead.block + 1, true)))
192
-
193
- const txValidationResults = await Promise.all(activeTransactions.map(async tx => ([tx, await validateTransaction(
194
- { ...this.context, chainId: this.params.chainId },
195
- tx,
196
- this.additionalPendingTransactionValidators,
197
- )])))
198
-
199
- const validTransactions = txValidationResults.filter((
200
- [, errors],
201
- ) => errors.length === 0).map(([tx]) => tx) as SignedHydratedTransactionWithStorageMeta[]
202
-
203
- const invalidTransactions = txValidationResults.filter((
204
- [, errors],
205
- ) => errors.length > 0).map(([tx]) => tx) as SignedHydratedTransactionWithStorageMeta[]
206
-
207
- if (invalidTransactions.length > 0) {
208
- this.logger?.warn(`getPendingTransactions: Found ${invalidTransactions.length} invalid pending transactions`)
209
- for (const tx of invalidTransactions) {
210
- this.logger?.warn(tx[0]._hash)
211
- }
212
- }
213
-
214
- // Add the valid hydrated transactions to the result set.
215
- foundPendingTransactions.push(...validTransactions)
216
- }
217
-
218
- if (foundPendingTransactions.length > 0) {
219
- this.logger?.log(`getPendingTransactions: Found ${foundPendingTransactions.length} pending transactions`)
220
- for (const tx of foundPendingTransactions) {
221
- this.logger?.log(tx[0]._hash)
222
- }
223
- }
224
-
225
- return foundPendingTransactions
226
- }, BasePendingTransactionsService.MutexPriority.ReadTransactions)
227
- }, this.context)
228
- }
229
-
230
- private async cleanupWorker() {
231
- return await this._updateCuratedPendingTransactionsArchivistMutex.runExclusive(async () => {
232
- const lastHead = await findMostRecentBlock(this.chainArchivist)
233
- if (isDefined(lastHead)) await this.pruneCuratedPendingTransactionsArchivist(lastHead._hash)
234
- }, BasePendingTransactionsService.MutexPriority.PurgeTransactions)
235
- }
236
-
237
- private async countPendingTransactions() {
238
- if (this._countPendingTransactionsMutex.isLocked()) return
239
- await this._countPendingTransactionsMutex.runExclusive(async () => {
240
- const payloads = (await this._curatedPendingBundledTransactionsArchivist?.all()) ?? []
241
- this._pendingTransactionsCount = payloads.length
242
- })
243
- }
244
-
245
- private async filterAlreadyFinalizedTransactions(
246
- incomingTransactions: WithStorageMeta<PayloadBundle>[],
247
- ): Promise<WithStorageMeta<PayloadBundle>[]> {
248
- const incomingTransactionHashes = incomingTransactions.map(payload => payload.root)
249
- const finalizedTransactions = await this.chainArchivist.get(incomingTransactionHashes)
250
- const finalizedTransactionHashes = new Set(finalizedTransactions.map(item => item._hash))
251
- const nonFinalizedTransactions = incomingTransactions.filter(item => !finalizedTransactionHashes.has(item._hash))
252
- return nonFinalizedTransactions
253
- }
254
-
255
- private async insertNewTransactions(payloads: WithStorageMeta<PayloadBundle>[]) {
256
- if (payloads.length === 0) return
257
- return await this.spanAsync('InsertNewTransactions', async () => {
258
- return await this._updateCuratedPendingTransactionsArchivistMutex.runExclusive(async () => {
259
- // Check incoming transactions against finalized transactions
260
- const unprocessedTransactions = await this.filterAlreadyFinalizedTransactions(payloads)
261
- // Hydrate all unprocessed transactions
262
- const hydratedUnprocessedTransactions = (await Promise.all(unprocessedTransactions.map(async (tx) => {
263
- return await bundledPayloadToHydratedTransaction(tx)
264
- }))).filter(exists)
265
- // Filter to only valid transactions
266
- const validTransactions = await filterAsync(hydratedUnprocessedTransactions, async (tx) => {
267
- const errors = await validateTransaction({ ...this.context, chainId: this.params.chainId }, tx, [TransactionJsonSchemaValidator])
268
- if (errors.length > 0) {
269
- this.logger?.warn('validateTransaction', errors)
270
- }
271
- return errors.length > 0 ? false : true
272
- })
273
- if (validTransactions.length > 0) {
274
- const bundledTransactions = validTransactions.map(tx => hydratedTransactionToPayloadBundle(tx))
275
- await this.pendingBundledTransactionsLocalArchivist.insert(bundledTransactions)
276
- }
277
- }, BasePendingTransactionsService.MutexPriority.InsertNewTransactions)
278
- }, this.context)
279
- }
280
-
281
- /**
282
- * Marks any included transactions in the provided payloads for removal preventing them
283
- * from being included in the curated pending transactions archivist and from being offered
284
- * during the next retrieval of pending transactions.
285
- * @param payloads An array of payloads that may contain transactions.
286
- */
287
- private markAnyIncludedTransactionsForRemoval(payloads: WithStorageMeta<Payload>[]) {
288
- const hashes = payloads.filter(isTransactionBoundWitnessWithStorageMeta).map(p => p._hash)
289
- for (const hash of hashes) {
290
- this._removablePendingTransactionHashes.add(hash)
291
- }
292
- }
293
-
294
- private async pruneCuratedPendingTransactionsArchivist(head: Hash) {
295
- return await this.spanAsync('pruneCuratedPendingTransactionsArchivist', async () => {
296
- const foundPendingTransactionsToDeleteHashes: Hash[] = []
297
-
298
- let cursor: Sequence | undefined
299
- let [lastHead] = filterAs(await this.chainArchivist.get([head]), x => asBlockBoundWitnessWithHashMeta(x))
300
-
301
- // Continue fetching until the desired number of transactions is reached.
302
- while (isDefined(lastHead)) {
303
- // Fetch the next batch of payloads
304
- const pendingBundledTransactions = await this.pendingBundledTransactionsLocalArchivist.next({
305
- limit: 100,
306
- order: 'asc',
307
- cursor,
308
- }) as WithStorageMeta<PayloadBundle>[]
309
-
310
- // Exit if no more payloads are available.
311
- if (pendingBundledTransactions.length === 0) {
312
- break
313
- }
314
-
315
- // Update the cursor for the next iteration to fetch subsequent payloads.
316
- cursor = pendingBundledTransactions.at(-1)?._sequence
317
-
318
- // Filter out bundles that are marked as removable.
319
- const deletedTransactionBundles = pendingBundledTransactions.filter(tx =>
320
- this._removablePendingTransactionHashes.has(tx.root))
321
-
322
- // Queue the hashes of deletable transactions for deletion and cleanup.
323
- foundPendingTransactionsToDeleteHashes.push(
324
- ...deletedTransactionBundles.map(tx => tx._hash).filter(exists),
325
- )
326
-
327
- // Keep only those payloads that are not marked for deletion.
328
- const undeletedTransactionBundles = pendingBundledTransactions.filter(tx =>
329
- !this._removablePendingTransactionHashes.has(tx.root))
330
-
331
- // Convert each undeleted payload bundle into a hydrated transaction.
332
- const transactions = (await Promise.all(
333
- undeletedTransactionBundles.map(p => bundledPayloadToHydratedTransaction(p)),
334
- )).filter(exists)
335
-
336
- // Find expired transactions based on the last supplied head
337
- const expiredTransactions = transactions.filter(isTransactionExpired(asXL1BlockNumber(lastHead.block + 1, true)))
338
- // Find the corresponding bundle hashes for the expired transactions
339
- const expiredBundleHashes = expiredTransactions
340
- .map(expiredHydratedTx =>
341
- // Find the corresponding payload bundle hash for the expired transaction
342
- pendingBundledTransactions.find(bundledTx => bundledTx.root === expiredHydratedTx[0]._hash)?._hash)
343
- .filter(exists)
344
- // Mark all expired bundled transactions for deletion.
345
- foundPendingTransactionsToDeleteHashes.push(...expiredBundleHashes)
346
- }
347
-
348
- // Actually delete the marked payload bundles from the archivist
349
- const deletedHashes = await this.pendingBundledTransactionsLocalArchivist.delete(foundPendingTransactionsToDeleteHashes)
350
-
351
- // Remove all deleted hashes from the "pending delete" set now that they are deleted
352
- for (const payload of deletedHashes) {
353
- this._removablePendingTransactionHashes.delete(payload._hash)
354
- }
355
-
356
- if (deletedHashes.length > 0) {
357
- this.logger?.log(`foundPendingTransactionsToDeleteHashes: Found ${deletedHashes.length} deletable transactions`)
358
- for (const payload of deletedHashes) {
359
- this.logger?.log(payload._hash)
360
- }
361
- }
362
- }, this.context)
363
- }
364
- }
365
-
366
- /**
367
- * Checks if a transaction is expired for a given block.
368
- * @param block The block number to check against the transaction's validity period.
369
- * @returns True if the transaction is expired for the given block, false otherwise.
370
- */
371
- const isTransactionExpired = (block: XL1BlockNumber) =>
372
- ([txBw]: SignedHydratedTransactionWithHashMeta): boolean =>
373
- txBw.exp < block
374
-
375
- /**
376
- * Checks if a transaction is active for a given block.
377
- * @param block The block number to check against the transaction's validity period.
378
- * @returns True if the transaction is active for the given block, false otherwise.
379
- */
380
- const isTransactionActive = (block: XL1BlockNumber) =>
381
- ([txBw]: SignedHydratedTransactionWithHashMeta): boolean =>
382
- txBw.nbf <= block && txBw.exp >= block
@@ -1,14 +0,0 @@
1
- import { PayloadBuilder } from '@xyo-network/payload-builder'
2
- import type { PayloadBundle, WithStorageMeta } from '@xyo-network/payload-model'
3
- import type { SignedHydratedTransactionWithHashMeta } from '@xyo-network/xl1-sdk'
4
- import { asSignedTransactionBoundWitnessWithHashMeta } from '@xyo-network/xl1-sdk'
5
-
6
- export const bundledPayloadToHydratedTransaction = async (
7
- payload: WithStorageMeta<PayloadBundle>,
8
- ): Promise<SignedHydratedTransactionWithHashMeta | undefined> => {
9
- const withHashMeta = await PayloadBuilder.addHashMeta(payload.payloads)
10
- const tx = asSignedTransactionBoundWitnessWithHashMeta(withHashMeta.find(p => p._hash === payload.root))
11
- if (tx) {
12
- return [tx, withHashMeta.filter(p => p._hash !== payload.root)]
13
- }
14
- }