@xyo-network/chain-services 1.19.13 → 1.19.15

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 (26) hide show
  1. package/dist/neutral/PendingTransactions/bundledPayloadToHydratedTransaction.d.ts.map +1 -1
  2. package/dist/neutral/PendingTransactions/hydratedTransactionToPayloadBundle.d.ts.map +1 -1
  3. package/dist/neutral/index.d.ts +0 -1
  4. package/dist/neutral/index.d.ts.map +1 -1
  5. package/dist/neutral/index.mjs +14 -262
  6. package/dist/neutral/index.mjs.map +1 -1
  7. package/dist/neutral/simple/block/runner/SimpleBlockRunner.d.ts +4 -1
  8. package/dist/neutral/simple/block/runner/SimpleBlockRunner.d.ts.map +1 -1
  9. package/package.json +27 -22
  10. package/src/PendingTransactions/bundledPayloadToHydratedTransaction.ts +1 -1
  11. package/src/PendingTransactions/hydratedTransactionToPayloadBundle.ts +1 -1
  12. package/src/index.ts +0 -1
  13. package/src/simple/block/runner/SimpleBlockRunner.ts +10 -11
  14. package/src/simple/block/runner/generateTransactionFeeTransfers.ts +1 -1
  15. package/dist/neutral/StakeIntent/XyoStakeIntentService.d.ts +0 -47
  16. package/dist/neutral/StakeIntent/XyoStakeIntentService.d.ts.map +0 -1
  17. package/dist/neutral/StakeIntent/index.d.ts +0 -3
  18. package/dist/neutral/StakeIntent/index.d.ts.map +0 -1
  19. package/dist/neutral/StakeIntent/lib/getBlockSignedStakeDeclarations.d.ts +0 -4
  20. package/dist/neutral/StakeIntent/lib/getBlockSignedStakeDeclarations.d.ts.map +0 -1
  21. package/dist/neutral/StakeIntent/lib/index.d.ts +0 -2
  22. package/dist/neutral/StakeIntent/lib/index.d.ts.map +0 -1
  23. package/src/StakeIntent/XyoStakeIntentService.ts +0 -259
  24. package/src/StakeIntent/index.ts +0 -2
  25. package/src/StakeIntent/lib/getBlockSignedStakeDeclarations.ts +0 -47
  26. package/src/StakeIntent/lib/index.ts +0 -1
@@ -1,7 +1,7 @@
1
1
  import type { Hash } from '@xylabs/sdk-js'
2
- import { PayloadBuilder } from '@xyo-network/payload-builder'
3
2
  import type { PayloadBundle } from '@xyo-network/payload-model'
4
3
  import { PayloadBundleSchema } from '@xyo-network/payload-model'
4
+ import { PayloadBuilder } from '@xyo-network/sdk-js'
5
5
  import type { SignedHydratedTransactionWithHashMeta } from '@xyo-network/xl1-sdk'
6
6
  import { flattenHydratedTransaction } from '@xyo-network/xl1-sdk'
7
7
 
package/src/index.ts CHANGED
@@ -6,5 +6,4 @@ export * from './model/index.ts'
6
6
  export * from './NetworkStakeStepReward/index.ts'
7
7
  export * from './PendingTransactions/index.ts'
8
8
  export * from './simple/index.ts'
9
- export * from './StakeIntent/index.ts'
10
9
  export * from './StepStake/index.ts'
@@ -8,8 +8,8 @@ import {
8
8
  BlockRewardDiviner, FixedPercentageBlockRewardDiviner, FixedPercentageBlockRewardDivinerConfigSchema,
9
9
  } from '@xyo-network/chain-modules'
10
10
  import { buildNextBlock } from '@xyo-network/chain-protocol'
11
- import { PayloadBuilder } from '@xyo-network/payload-builder'
12
11
  import { WithHashMeta } from '@xyo-network/payload-model'
12
+ import { PayloadBuilder } 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,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,259 +0,0 @@
1
- import {
2
- Address, asAddress, assertEx, filterAs, Hash,
3
- isUndefined,
4
- } from '@xylabs/sdk-js'
5
- import { ArchivistInstance, ArchivistNextOptions } from '@xyo-network/archivist-model'
6
- import {
7
- analyzeChain, ChainStakeIntentAnalyzer,
8
- isChainSummaryStakeIntent,
9
- } from '@xyo-network/chain-analyze'
10
- import {
11
- DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS,
12
- findFirstMatching, IntervalMap,
13
- SerializedIntervalMap,
14
- } from '@xyo-network/chain-utils'
15
- import { PayloadBuilder } from '@xyo-network/payload-builder'
16
- import { Payload, WithStorageMeta } from '@xyo-network/payload-model'
17
- import {
18
- AbstractCreatableProvider,
19
- asChainIndexingServiceStateWithStorageMeta,
20
- BlockViewer,
21
- BlockViewerMoniker,
22
- ChainIndexingServiceState, ChainIndexingServiceStateSchema, ChainStakeViewer,
23
- ChainStakeViewerMoniker,
24
- creatableProvider,
25
- isChainIndexingServiceState,
26
- readPayloadMapFromStore,
27
- StakeIntentService,
28
- timeBudget,
29
- } from '@xyo-network/xl1-sdk'
30
- import {
31
- asBlockBoundWitness, asBlockBoundWitnessWithStorageMeta, asChainStakeIntent, type Intent,
32
- } from '@xyo-network/xl1-sdk'
33
- import { Mutex } from 'async-mutex'
34
- import { LRUCache } from 'lru-cache'
35
-
36
- import { BaseServiceParams } from '../model/index.ts'
37
-
38
- export interface XyoStakeIntentServiceParams extends BaseServiceParams {
39
- blockViewer: BlockViewer
40
- chainArchivist: ArchivistInstance
41
- chainStakeViewer: ChainStakeViewer
42
- stakeIntentStateArchivist: ArchivistInstance
43
- }
44
-
45
- /**
46
- * The number of blocks to periodically persist state
47
- */
48
- // const STATE_PERSISTENCE_INTERVAL = 60n
49
-
50
- const ACTIVE_STAKE_TTL = 1000 * 60 * 60 * 2 // 2 hours in milliseconds
51
- const NO_ACTIVE_STAKE_TTL = 1000 * 2 // 2 seconds in milliseconds
52
- const STAKE_CACHE_MAX_ENTRIES = 10_000
53
-
54
- @creatableProvider()
55
- export class XyoStakeIntentService extends AbstractCreatableProvider<XyoStakeIntentServiceParams> implements StakeIntentService {
56
- static readonly defaultMoniker = 'StakeIntent'
57
- static readonly dependencies = []
58
- static readonly monikers = [XyoStakeIntentService.defaultMoniker]
59
- moniker = 'StakeIntent'
60
- // TODO: Use hash instead of block number to handle chain reorgs
61
- protected _lastIndexedBlockHash: Hash | undefined = undefined
62
- // TODO: Interval tree per declaration (bank, validator, etc.)
63
-
64
- // Ideally move to DataIntervalTree to handle declared
65
- // ranges as it enables range queries in O(min(n, k * log n)) time,
66
- // where k is the number of intervals in the output list time
67
- // Currently using set based because it's simpler, equivalent
68
- // in performance for small sets, and (most importantly) easily
69
- // persisted so we can recover state on restart.
70
- protected _producers: IntervalMap<Address> = new IntervalMap()
71
- protected _stakeCache = new LRUCache<Address, bigint>({ max: STAKE_CACHE_MAX_ENTRIES })
72
- protected _updateMutex = new Mutex()
73
-
74
- private _blockViewer?: BlockViewer
75
- private _chainStakeViewer?: ChainStakeViewer
76
-
77
- protected get blockViewer() {
78
- return this._blockViewer!
79
- }
80
-
81
- protected get chainArchivist() {
82
- return assertEx(this.params.chainArchivist!, () => 'chainArchivist not set')
83
- }
84
-
85
- protected get chainStakeViewer() {
86
- return this._chainStakeViewer!
87
- }
88
-
89
- protected get stakeIntentStateArchivist() {
90
- return assertEx(this.params.stakeIntentStateArchivist!, () => 'stakeIntentStateArchivist not set')
91
- }
92
-
93
- static override async paramsHandler(params: Partial<XyoStakeIntentServiceParams>): Promise<XyoStakeIntentServiceParams> {
94
- return {
95
- ...await super.paramsHandler(params),
96
- chainArchivist: assertEx(params?.chainArchivist, () => 'chainArchivist is required'),
97
- stakeIntentStateArchivist: assertEx(params?.stakeIntentStateArchivist, () => 'stakeIntentStateArchivist is required'),
98
- } as XyoStakeIntentServiceParams
99
- }
100
-
101
- override async createHandler() {
102
- this._blockViewer = await this.locator.getInstance(BlockViewerMoniker)
103
- this._chainStakeViewer = await this.locator.getInstance(ChainStakeViewerMoniker)
104
- const head = await this.blockViewer.currentBlock()
105
- if (isUndefined(head)) return
106
- await this.recoverState(head[0]._hash)
107
- }
108
-
109
- async getDeclaredCandidateRanges(address: Address, intent: Intent): Promise<Readonly<Readonly<[number, number]>[]>> {
110
- await Promise.resolve()
111
- assertEx(intent === 'producer', () => `Support not yet added for intent ${intent}`)
112
- const results = this._producers.get(address)
113
- return results ?? []
114
- }
115
-
116
- async getDeclaredCandidatesForBlock(block: number, intent: Intent): Promise<Address[]> {
117
- return await this.spanAsync('getDeclaredCandidatesForBlock', async () => {
118
- assertEx(intent === 'producer', () => `Support not yet added for intent ${intent}`)
119
- const results = this._producers.findAllContaining(block)
120
- const candidates = [...results]
121
- const requiredMinimumStake = this.getRequiredMinimumStakeForIntent(intent)
122
- const validCandidates = await this.filterToValidStake(candidates, this.chainStakeViewer, requiredMinimumStake)
123
- return validCandidates
124
- }, this.context)
125
- }
126
-
127
- getRequiredMinimumStakeForIntent(intent: Intent): bigint {
128
- switch (intent) {
129
- case 'producer': {
130
- const { minStake } = this.params.context.config.actors.producer
131
- return BigInt(minStake)
132
- }
133
- }
134
- }
135
-
136
- async isStakedForBlock(block: number, intent: Intent, address: Address): Promise<boolean> {
137
- const candidates = await this.getDeclaredCandidatesForBlock(block, intent)
138
- return candidates.includes(address)
139
- }
140
-
141
- override async startHandler(): Promise<void> {
142
- await this.updateIndex(true)
143
- }
144
-
145
- private async filterToValidStake(
146
- candidates: Address[],
147
- chainStakeViewer: ChainStakeViewer,
148
- requiredMinimumStake: bigint,
149
- ): Promise<Address[]> {
150
- type CandidateStake = { candidate: Address; stake: bigint }
151
-
152
- // Find the stake for each candidate
153
- const candidatesWithStake: CandidateStake[] = await Promise.all(
154
- candidates.map(async (candidate) => {
155
- // Check if the stake is already cached
156
- const stake = this._stakeCache.get(candidate)
157
- if (stake === undefined) {
158
- // Fetch from chainStakeViewer if not cached
159
- const activeStake = await chainStakeViewer.activeByStaked(candidate)
160
- if (activeStake > 0n) {
161
- // Store result in cache
162
- this._stakeCache.set(candidate, activeStake, { ttl: ACTIVE_STAKE_TTL })
163
- } else {
164
- this._stakeCache.set(candidate, activeStake, { ttl: NO_ACTIVE_STAKE_TTL })
165
- }
166
- return { candidate, stake: activeStake }
167
- } else {
168
- return { candidate, stake }
169
- }
170
- }),
171
- )
172
-
173
- // Filter out candidates whose stake is greater than or equal to the required minimum
174
- return candidatesWithStake
175
- .filter(({ stake }) => stake >= requiredMinimumStake)
176
- .map(({ candidate }) => candidate)
177
- }
178
-
179
- private async persistState(current: Hash): Promise<void> {
180
- const state = this._producers.serialize()
181
- const payload = new PayloadBuilder<ChainIndexingServiceState<SerializedIntervalMap>>({ schema: ChainIndexingServiceStateSchema })
182
- .fields({ endBlockHash: current, state })
183
- .build()
184
- await this.stakeIntentStateArchivist.insert([payload])
185
- }
186
-
187
- private async recoverState(current: Hash): Promise<void> {
188
- return await timeBudget('XyoStakeIntentService.recoverState', console, async () => {
189
- const currentBlock = assertEx(asBlockBoundWitness((await this.chainArchivist.get([current]))?.[0]), () => `Block ${current} not found`)
190
- const currentBlockNum = currentBlock.block
191
- // Find last state before current head (in case of rollback, we indexed past it on an uncle chain, etc.)
192
- const opts: ArchivistNextOptions = { ...DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS }
193
- while (true) {
194
- const predicate = (p: WithStorageMeta<Payload>) => {
195
- const state = asChainIndexingServiceStateWithStorageMeta(p)
196
- return state ? true : false
197
- }
198
- const state = await findFirstMatching(this.stakeIntentStateArchivist, predicate, opts)
199
- if (isChainIndexingServiceState<SerializedIntervalMap>(state)) {
200
- const indexed = (await this.chainArchivist.get([state.endBlockHash]))?.[0]
201
- const indexedBlock = asBlockBoundWitnessWithStorageMeta(indexed)
202
- if (indexedBlock) {
203
- const indexedBlockNum = indexedBlock.block
204
- if (indexedBlockNum <= currentBlockNum) {
205
- const data = state.state as SerializedIntervalMap
206
- this._producers = new IntervalMap(data)
207
- this._lastIndexedBlockHash = indexedBlock._hash
208
- break
209
- }
210
- }
211
- } else {
212
- // No state found, start from genesis
213
- break
214
- }
215
- opts.open = true
216
- }
217
- }, 2000, true)
218
- }
219
-
220
- private async updateIndex(displayProgress = false): Promise<void> {
221
- if (this._updateMutex.isLocked()) {
222
- return
223
- }
224
- await this._updateMutex.runExclusive(async () => {
225
- return await this.spanAsync('updateIndex', async () => {
226
- const currentHead = (await this.blockViewer.currentBlock())[0]
227
- if (isUndefined(currentHead)) return
228
- const currentHeadHash = currentHead._hash
229
- const chainMap = readPayloadMapFromStore<WithStorageMeta<Payload>>(this.chainArchivist)
230
- const result = await analyzeChain(
231
- { ...this.context, chainMap },
232
- [new ChainStakeIntentAnalyzer('producer')],
233
- currentHeadHash,
234
- this._lastIndexedBlockHash,
235
- )
236
- const signedDeclarations = filterAs(result.find(isChainSummaryStakeIntent)?.intents ?? [], asChainStakeIntent)
237
- if (currentHead.block === undefined) return
238
- const currentHeadBlockNum = currentHead.block
239
- if (displayProgress) this.logger?.log(`Updating index through 0x${currentHeadBlockNum}`)
240
- for (const signedDeclaration of signedDeclarations) {
241
- const { exp, nbf } = signedDeclaration
242
- const start = nbf
243
- const stop = exp
244
- const address = asAddress(signedDeclaration?.from)
245
- if (start !== undefined && stop !== undefined && address !== undefined) {
246
- this._producers.insert(address, start, stop)
247
- }
248
- }
249
- /*
250
- if (index % STATE_PERSISTENCE_INTERVAL === 0n) {
251
- if (displayProgress) this.logger?.info(`Persisting state at block ${index}`)
252
- await this.persistState(await PayloadBuilder.hash(block))
253
- }
254
- */
255
- this._lastIndexedBlockHash = currentHeadHash
256
- }, this.context)
257
- })
258
- }
259
- }
@@ -1,2 +0,0 @@
1
- export * from './lib/index.ts'
2
- export * from './XyoStakeIntentService.ts'
@@ -1,47 +0,0 @@
1
- import type { Hash } from '@xylabs/sdk-js'
2
- import { exists, filterAs } from '@xylabs/sdk-js'
3
- import type { ArchivistInstance } from '@xyo-network/archivist-model'
4
- import type { BoundWitness } from '@xyo-network/boundwitness-model'
5
- import { isBoundWitness } from '@xyo-network/boundwitness-model'
6
- import { payloadSchemasContains } from '@xyo-network/boundwitness-validator'
7
- import { BoundWitnessWrapper } from '@xyo-network/boundwitness-wrapper'
8
- import type {
9
- BlockBoundWitness, ChainStakeIntent, Intent,
10
- } from '@xyo-network/xl1-sdk'
11
- import { asChainStakeIntent, ChainStakeIntentSchema } from '@xyo-network/xl1-sdk'
12
-
13
- export const getBlockSignedStakeDeclarations = async (block: BlockBoundWitness, archivist: ArchivistInstance, intent: Intent): Promise<ChainStakeIntent[]> => {
14
- // Get payloads in block
15
- const blockData = await archivist.get(block.payload_hashes)
16
- // Filter Payloads in block to BoundWitnesses
17
- const bwsFromBlock = blockData.filter(x => isBoundWitness(x))
18
- // Filter to BoundWitnesses with StakeIntent payloads
19
- const bwsFromBlockWithDeclarations = bwsFromBlock.filter(bw => payloadSchemasContains(bw, ChainStakeIntentSchema))
20
- // Filter to only valid signed BWs
21
- const validBlockBwsWithDeclarations = await filterToValidSignedBoundWitnesses(bwsFromBlockWithDeclarations)
22
- return (await Promise.all(validBlockBwsWithDeclarations.map(async (bw) => {
23
- // Get staked intent hashes from signed declarations
24
- const stakeIntentHashes = validBlockBwsWithDeclarations
25
- .flatMap(mapBoundWitnessToStakeIntentHashes)
26
- .filter(exists)
27
- // Get staked intent payloads
28
- const payloads = await archivist.get(stakeIntentHashes)
29
- // Filter payloads to staked intents
30
- const stakeIntents = filterAs(payloads, asChainStakeIntent)
31
- // that are producers
32
- .filter(p => p.intent === intent)
33
- // where the issuer of the intent is also the signer of this BW
34
- .filter(p => bw.addresses.includes(p.from))
35
-
36
- return stakeIntents
37
- }))).flat()
38
- }
39
-
40
- const filterToValidSignedBoundWitnesses = async (bws: BoundWitness[]): Promise<BoundWitness[]> => {
41
- const validBwIndexes = await Promise.all(bws.map(bw => BoundWitnessWrapper.parse(bw).getValid()))
42
- return bws.filter((_, index) => validBwIndexes[index])
43
- }
44
-
45
- const mapBoundWitnessToStakeIntentHashes = (bw: BoundWitness): (Hash | undefined)[] => {
46
- return bw.payload_schemas.map((schema, index) => schema === ChainStakeIntentSchema ? bw.payload_hashes[index] : undefined)
47
- }
@@ -1 +0,0 @@
1
- export * from './getBlockSignedStakeDeclarations.ts'