@xyo-network/chain-services 1.16.22 → 1.16.24

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 (28) hide show
  1. package/dist/neutral/AccountBalance/BaseAccountBalanceService.d.ts +15 -7
  2. package/dist/neutral/AccountBalance/BaseAccountBalanceService.d.ts.map +1 -1
  3. package/dist/neutral/AccountBalance/accountBalanceServiceFromArchivist.d.ts +2 -2
  4. package/dist/neutral/AccountBalance/accountBalanceServiceFromArchivist.d.ts.map +1 -1
  5. package/dist/neutral/BlockProducer/BaseBlockProducerService.d.ts +12 -3
  6. package/dist/neutral/BlockProducer/BaseBlockProducerService.d.ts.map +1 -1
  7. package/dist/neutral/ChainService/Memory/Memory.d.ts +3 -0
  8. package/dist/neutral/ChainService/Memory/Memory.d.ts.map +1 -1
  9. package/dist/neutral/PendingTransactions/BasePendingTransactions.d.ts.map +1 -1
  10. package/dist/neutral/Schemas/BaseSchemasService.d.ts +13 -0
  11. package/dist/neutral/Schemas/BaseSchemasService.d.ts.map +1 -0
  12. package/dist/neutral/Schemas/index.d.ts +2 -0
  13. package/dist/neutral/Schemas/index.d.ts.map +1 -0
  14. package/dist/neutral/StakeIntent/XyoStakeIntentService.d.ts.map +1 -1
  15. package/dist/neutral/index.d.ts +1 -0
  16. package/dist/neutral/index.d.ts.map +1 -1
  17. package/dist/neutral/index.mjs +234 -142
  18. package/dist/neutral/index.mjs.map +1 -1
  19. package/package.json +16 -15
  20. package/src/AccountBalance/BaseAccountBalanceService.ts +36 -14
  21. package/src/AccountBalance/accountBalanceServiceFromArchivist.ts +2 -2
  22. package/src/BlockProducer/BaseBlockProducerService.ts +20 -5
  23. package/src/ChainService/Memory/Memory.ts +14 -4
  24. package/src/PendingTransactions/BasePendingTransactions.ts +12 -0
  25. package/src/Schemas/BaseSchemasService.ts +34 -0
  26. package/src/Schemas/index.ts +1 -0
  27. package/src/StakeIntent/XyoStakeIntentService.ts +47 -42
  28. package/src/index.ts +1 -0
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.16.22",
4
+ "version": "1.16.24",
5
5
  "description": "XYO Layer One SDK Services",
6
6
  "homepage": "https://xylabs.com",
7
7
  "bugs": {
@@ -40,38 +40,39 @@
40
40
  ],
41
41
  "dependencies": {
42
42
  "@opentelemetry/api": "~1.9.0",
43
- "@xylabs/sdk-js": "~5.0.37",
44
- "@xylabs/telemetry": "~5.0.37",
43
+ "@xylabs/sdk-js": "~5.0.39",
44
+ "@xylabs/telemetry": "~5.0.39",
45
45
  "@xyo-network/account-model": "~5.1.24",
46
46
  "@xyo-network/archivist-memory": "~5.1.24",
47
47
  "@xyo-network/archivist-model": "~5.1.24",
48
48
  "@xyo-network/boundwitness-model": "~5.1.24",
49
49
  "@xyo-network/boundwitness-validator": "~5.1.24",
50
50
  "@xyo-network/boundwitness-wrapper": "~5.1.24",
51
- "@xyo-network/chain-analyze": "~1.16.22",
52
- "@xyo-network/chain-modules": "~1.16.22",
53
- "@xyo-network/chain-protocol": "~1.16.22",
54
- "@xyo-network/chain-utils": "~1.16.22",
51
+ "@xyo-network/chain-analyze": "~1.16.24",
52
+ "@xyo-network/chain-modules": "~1.16.24",
53
+ "@xyo-network/chain-protocol": "~1.16.24",
54
+ "@xyo-network/chain-utils": "~1.16.24",
55
55
  "@xyo-network/payload-builder": "~5.1.24",
56
56
  "@xyo-network/payload-model": "~5.1.24",
57
57
  "@xyo-network/typechain": "~4.0.10",
58
- "@xyo-network/xl1-protocol": "~1.13.11",
59
- "@xyo-network/xl1-protocol-sdk": "~1.16.22",
60
- "@xyo-network/xl1-validation": "~1.16.22",
61
- "@xyo-network/xl1-wrappers": "~1.16.22",
58
+ "@xyo-network/xl1-protocol": "~1.13.13",
59
+ "@xyo-network/xl1-protocol-sdk": "~1.16.24",
60
+ "@xyo-network/xl1-validation": "~1.16.24",
61
+ "@xyo-network/xl1-wrappers": "~1.16.24",
62
62
  "async-mutex": "~0.5.0",
63
63
  "ethers": "6.15.0",
64
- "lru-cache": "~11.2.2"
64
+ "lru-cache": "~11.2.2",
65
+ "zod": "~4.1.12"
65
66
  },
66
67
  "devDependencies": {
67
68
  "@types/node": "~24.10.1",
68
- "@xylabs/sdk-js": "~5.0.37",
69
+ "@xylabs/sdk-js": "~5.0.39",
69
70
  "@xylabs/ts-scripts-yarn3": "~7.2.8",
70
71
  "@xylabs/tsconfig": "~7.2.8",
71
- "@xylabs/vitest-extended": "~5.0.37",
72
+ "@xylabs/vitest-extended": "~5.0.39",
72
73
  "@xyo-network/account": "~5.1.24",
73
74
  "@xyo-network/account-model": "~5.1.24",
74
- "@xyo-network/chain-validation": "~1.16.22",
75
+ "@xyo-network/chain-validation": "~1.16.24",
75
76
  "@xyo-network/wallet": "~5.1.24",
76
77
  "eslint": "^9.39.1",
77
78
  "tslib": "~2.8.1",
@@ -1,12 +1,12 @@
1
1
  import {
2
- Address, creatable, Hash,
2
+ Address, assertEx, creatable, Hash,
3
3
  } from '@xylabs/sdk-js'
4
4
  import { spanRootAsync } from '@xylabs/telemetry'
5
5
  import { ReadArchivist } from '@xyo-network/archivist-model'
6
6
  import { AttoXL1, XL1BlockRange } from '@xyo-network/xl1-protocol'
7
7
  import {
8
8
  AccountBalanceHistoryItem,
9
- AccountBalanceService,
9
+ AccountBalanceViewer,
10
10
  balancesSummary,
11
11
  BalanceStepSummaryContext,
12
12
  BlockViewer,
@@ -14,11 +14,19 @@ import {
14
14
  SimpleAccountBalanceViewer,
15
15
  TransfersStepSummaryContext,
16
16
  } from '@xyo-network/xl1-protocol-sdk'
17
+ import z from 'zod'
17
18
 
18
19
  import { BaseService } from '../BaseService.ts'
19
20
  import { blockViewerFromChainIteratorAndArchivist } from '../blockViewerFromChainIteratorAndArchivist.ts'
20
21
  import { BaseServiceParams } from '../model/index.ts'
21
22
 
23
+ export const BaseAccountBalanceServiceParamsZod = z.object({
24
+ chainArchivist: z.object().loose(),
25
+ chainIterator: z.object().loose(),
26
+ context: z.object().loose(),
27
+ transferContext: z.object().loose(),
28
+ })
29
+
22
30
  export interface BaseAccountBalanceServiceParams extends BaseServiceParams {
23
31
  chainArchivist: ReadArchivist
24
32
  chainIterator: EventingChainBlockNumberIteratorService
@@ -27,26 +35,40 @@ export interface BaseAccountBalanceServiceParams extends BaseServiceParams {
27
35
  }
28
36
 
29
37
  @creatable()
30
- export class BaseAccountBalanceService extends BaseService<BaseAccountBalanceServiceParams> implements AccountBalanceService {
31
- protected accountBalanceViewer!: AccountBalanceService
38
+ export class BaseAccountBalanceService extends BaseService<BaseAccountBalanceServiceParams> implements AccountBalanceViewer {
39
+ protected accountBalanceViewer!: AccountBalanceViewer
32
40
  protected blockViewer!: BlockViewer
33
41
 
42
+ static override async paramsHandler(params?: Partial<BaseAccountBalanceServiceParams> | undefined): Promise<BaseAccountBalanceServiceParams> {
43
+ // TODO: Use a real zod and move the zod check to the AbstractCreatable class
44
+ BaseAccountBalanceServiceParamsZod.parse(params)
45
+ assertEx(params?.context?.head, () => 'BalanceStepSummaryContext is required in BaseAccountBalanceServiceParams')
46
+ return { ...(await super.paramsHandler(params)), ...params } as BaseAccountBalanceServiceParams
47
+ }
48
+
34
49
  async accountBalance(address: Address, headOrRange?: XL1BlockRange | Hash): Promise<AttoXL1> {
35
- const balances = await this.accountBalances([address], headOrRange)
50
+ const balances = await this.accountsBalances([address], headOrRange)
36
51
  return balances[address] ?? AttoXL1(0n)
37
52
  }
38
53
 
39
54
  async accountBalanceHistory(address: Address): Promise<AccountBalanceHistoryItem[]>
40
55
  async accountBalanceHistory(address: Address, head: Hash): Promise<AccountBalanceHistoryItem[]>
41
56
  async accountBalanceHistory(address: Address, range: XL1BlockRange): Promise<AccountBalanceHistoryItem[]>
42
- async accountBalanceHistory(address: Address, headOrRange?: Hash | XL1BlockRange): Promise<AccountBalanceHistoryItem[]> {
43
- return await this.accountBalanceViewer.accountBalanceHistory(address, headOrRange)
57
+ accountBalanceHistory(_address: Address, _headOrRange?: Hash | XL1BlockRange): Promise<AccountBalanceHistoryItem[]> {
58
+ throw new Error('Method not implemented.')
44
59
  }
45
60
 
46
- async accountBalances(address: Address[], _headOrRange?: XL1BlockRange | Hash): Promise<Partial<Record<Address, AttoXL1>>> {
61
+ async accountsBalances(address: Address[], _headOrRange?: Hash | XL1BlockRange): Promise<Partial<Record<Address, AttoXL1>>> {
47
62
  return await spanRootAsync('balances', async () => {
63
+ const context = {
64
+ head: this.params.context.head,
65
+ stepSemaphores: this.params.context.stepSemaphores,
66
+ store: this.params.context.store,
67
+ chainId: this.params.context.chainId,
68
+ summaryMap: this.params.context.summaryMap,
69
+ } satisfies BalanceStepSummaryContext
48
70
  const summary = await balancesSummary(
49
- this.params.context,
71
+ context,
50
72
  )
51
73
  const result: Record<Address, AttoXL1> = {}
52
74
  for (const addr of address) {
@@ -57,11 +79,11 @@ export class BaseAccountBalanceService extends BaseService<BaseAccountBalanceSer
57
79
  })
58
80
  }
59
81
 
60
- async accountBalancesHistories(addresses: Address[]): Promise<Partial<Record<Address, AccountBalanceHistoryItem[]>>>
61
- async accountBalancesHistories(addresses: Address[], head: Hash): Promise<Partial<Record<Address, AccountBalanceHistoryItem[]>>>
62
- async accountBalancesHistories(addresses: Address[], range: XL1BlockRange): Promise<Partial<Record<Address, AccountBalanceHistoryItem[]>>>
63
- async accountBalancesHistories(addresses: Address[], headOrRange?: Hash | XL1BlockRange): Promise<Partial<Record<Address, AccountBalanceHistoryItem[]>>> {
64
- return await this.accountBalanceViewer.accountBalancesHistories(addresses, headOrRange)
82
+ async accountsBalancesHistory(addresses: Address[]): Promise<Partial<Record<Address, AccountBalanceHistoryItem[]>>>
83
+ async accountsBalancesHistory(addresses: Address[], head: Hash): Promise<Partial<Record<Address, AccountBalanceHistoryItem[]>>>
84
+ async accountsBalancesHistory(addresses: Address[], range: XL1BlockRange): Promise<Partial<Record<Address, AccountBalanceHistoryItem[]>>>
85
+ accountsBalancesHistory(_addresses: Address[], _headOrRange?: Hash | XL1BlockRange): Promise<Partial<Record<Address, AccountBalanceHistoryItem[]>>> {
86
+ throw new Error('Method not implemented.')
65
87
  }
66
88
 
67
89
  override createHandler() {
@@ -5,7 +5,7 @@ import { findMostRecentBlock } from '@xyo-network/chain-protocol'
5
5
  import type { Payload, WithStorageMeta } from '@xyo-network/payload-model'
6
6
  import type { ChainId } from '@xyo-network/xl1-protocol'
7
7
  import { StepSizes } from '@xyo-network/xl1-protocol'
8
- import type { AccountBalanceService, BalancesStepSummary } from '@xyo-network/xl1-protocol-sdk'
8
+ import type { AccountBalanceViewer, BalancesStepSummary } from '@xyo-network/xl1-protocol-sdk'
9
9
  import { LruCacheMap, readPayloadMapFromStore } from '@xyo-network/xl1-protocol-sdk'
10
10
  import { Semaphore } from 'async-mutex'
11
11
 
@@ -15,7 +15,7 @@ import { BaseAccountBalanceService } from './BaseAccountBalanceService.ts'
15
15
  export const accountBalancesServiceFromArchivist = async (
16
16
  chainId: ChainId,
17
17
  archivist: ReadArchivist<WithStorageMeta<Payload>>,
18
- ): Promise<AccountBalanceService> => {
18
+ ): Promise<AccountBalanceViewer> => {
19
19
  const summaryMap = new LruCacheMap<string, BalancesStepSummary>({
20
20
  max: 100_000,
21
21
  allowStale: true,
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable max-statements */
2
2
  import {
3
- Address, asHash, assertEx, creatable,
3
+ Address, AddressZod, asHash, assertEx, creatable,
4
4
  exists,
5
5
  Hex,
6
6
  hexToBigInt,
@@ -21,8 +21,9 @@ import {
21
21
  Transfer, XYO_STEP_REWARD_ADDRESS,
22
22
  } from '@xyo-network/xl1-protocol'
23
23
  import {
24
- AccountBalanceService, BlockProducerService, Config, PendingTransactionsService, StakeIntentService, TimeSyncViewer,
24
+ AccountBalanceViewer, BlockProducerService, Config, PendingTransactionsService, StakeIntentService, TimeSyncViewer,
25
25
  } from '@xyo-network/xl1-protocol-sdk'
26
+ import z from 'zod'
26
27
 
27
28
  import { BaseService } from '../BaseService.ts'
28
29
  import { XyoValidatorParams } from '../ChainValidator/index.ts'
@@ -44,8 +45,16 @@ export const XYO_PRODUCER_REDECLARATION_DURATION = 10_000
44
45
  */
45
46
  export const XYO_PRODUCER_REDECLARATION_WINDOW = 500
46
47
 
48
+ export const BaseBlockProducerServiceParamsZod = z.object({
49
+ balanceService: z.object().loose(),
50
+ pendingTransactionsService: z.object().loose(),
51
+ rejectedTransactionsArchivist: z.object().loose(),
52
+ rewardAddress: AddressZod,
53
+ time: z.object().loose(),
54
+ })
55
+
47
56
  export interface BaseBlockProducerServiceParams extends XyoValidatorParams<Pick<Config, 'producer'>> {
48
- balanceService: AccountBalanceService
57
+ balanceService: AccountBalanceViewer
49
58
  pendingTransactionsService: PendingTransactionsService
50
59
  rejectedTransactionsArchivist: ArchivistInstance
51
60
  rewardAddress: Address
@@ -131,6 +140,12 @@ export class BaseBlockProducerService extends BaseService<BaseBlockProducerServi
131
140
  return assertEx(this.params.validateHydratedBlockState, () => 'validateHydratedBlockState is required')
132
141
  }
133
142
 
143
+ static override async paramsHandler(params?: Partial<BaseBlockProducerServiceParams> | undefined): Promise<BaseBlockProducerServiceParams> {
144
+ // TODO: Use a real zod and move the zod check to the AbstractCreatable class
145
+ BaseBlockProducerServiceParamsZod.parse(params)
146
+ return { ...(await super.paramsHandler(params)), ...params } as BaseBlockProducerServiceParams
147
+ }
148
+
134
149
  async next(head: WithStorageMeta<BlockBoundWitness>): Promise<HydratedBlock | undefined> {
135
150
  // If the block is for another chain, ignore
136
151
  if (head.chain !== this.chainId) return
@@ -228,7 +243,7 @@ export class BaseBlockProducerService extends BaseService<BaseBlockProducerServi
228
243
  // Build the block
229
244
  this.logger?.info(`Building block ${head.block + 1}`)
230
245
  const startBuild = Date.now()
231
- const stepRewardPoolBalance = (await this.balanceService.accountBalances([XYO_STEP_REWARD_ADDRESS]))[XYO_STEP_REWARD_ADDRESS]
246
+ const stepRewardPoolBalance = (await this.balanceService.accountsBalances([XYO_STEP_REWARD_ADDRESS]))[XYO_STEP_REWARD_ADDRESS]
232
247
  const block = await buildNextBlock(head, fundedNextBlockTransactions, blockPayloads, [this.account], XYO_STEP_REWARD_ADDRESS, stepRewardPoolBalance)
233
248
 
234
249
  this.logger?.info(
@@ -263,7 +278,7 @@ export class BaseBlockProducerService extends BaseService<BaseBlockProducerServi
263
278
  if (!transfer) return
264
279
  const totalTransferCost = Object.values(transfer?.transfers).reduce((acc, t) => acc + hexToBigInt(t ?? '00' as Hex), 0n)
265
280
  if (validateBalances) {
266
- const balance = (await this.balanceService.accountBalances([transfer.from]))[transfer.from] ?? AttoXL1(0n)
281
+ const balance = (await this.balanceService.accountsBalances([transfer.from]))[transfer.from] ?? AttoXL1(0n)
267
282
  if (balance >= totalTransferCost) {
268
283
  fundedTransfers.push(transfer)
269
284
  return tx
@@ -1,20 +1,25 @@
1
1
  import type { Address } from '@xylabs/sdk-js'
2
- import { ZERO_ADDRESS } from '@xylabs/sdk-js'
2
+ import {
3
+ assertEx, toAddress, ZERO_ADDRESS,
4
+ } from '@xylabs/sdk-js'
3
5
  import type { ChainService, Config } from '@xyo-network/xl1-protocol-sdk'
4
6
 
5
7
  import { BaseService } from '../../BaseService.ts'
6
8
  import type { BaseServiceParams } from '../../model/index.ts'
7
9
 
8
- export interface MemoryChainServiceParams extends BaseServiceParams<Pick<Config, 'producer'>> {}
10
+ export interface MemoryChainServiceParams extends BaseServiceParams<Pick<Config, 'producer'>> {
11
+ chainId: Address
12
+ }
9
13
 
10
14
  /**
11
15
  * A class that represents a chain stake as backed in memory
12
16
  */
13
17
  export class MemoryChainService extends BaseService<MemoryChainServiceParams> implements ChainService {
18
+ protected _chainId: Address | undefined
14
19
  protected _simulatedStake: bigint = 1n
15
20
 
16
21
  get chainId(): Address {
17
- return ZERO_ADDRESS
22
+ return assertEx(this._chainId, () => 'Chain ID not set')
18
23
  }
19
24
 
20
25
  async active(): Promise<bigint> {
@@ -34,7 +39,7 @@ export class MemoryChainService extends BaseService<MemoryChainServiceParams> im
34
39
  }
35
40
 
36
41
  override createHandler(): void {
37
- const { minStake } = this.params.config.producer
42
+ const { minStake = 1 } = this.params.config.producer ?? {}
38
43
  this._simulatedStake = BigInt(minStake)
39
44
  }
40
45
 
@@ -85,4 +90,9 @@ export class MemoryChainService extends BaseService<MemoryChainServiceParams> im
85
90
  async withdrawnByStaker(_staker: string): Promise<bigint> {
86
91
  return await Promise.resolve(0n)
87
92
  }
93
+
94
+ protected override async startHandler(): Promise<void> {
95
+ await super.startHandler()
96
+ this._chainId = this.params.chainId ?? toAddress(1n)
97
+ }
88
98
  }
@@ -186,10 +186,22 @@ export class BasePendingTransactionsService extends BaseService<BasePendingTrans
186
186
  { chainId: this.chainId },
187
187
  this.additionalPendingTransactionValidators,
188
188
  )])))
189
+
189
190
  const validTransactions = txValidationResults.filter((
190
191
  [, errors],
191
192
  ) => errors.length === 0).map(([tx]) => tx) as SignedHydratedTransactionWithStorageMeta[]
192
193
 
194
+ const invalidTransactions = txValidationResults.filter((
195
+ [, errors],
196
+ ) => errors.length > 0).map(([tx]) => tx) as SignedHydratedTransactionWithStorageMeta[]
197
+
198
+ if (invalidTransactions.length > 0) {
199
+ this.logger?.warn(`getPendingTransactions: Found ${invalidTransactions.length} invalid pending transactions`)
200
+ for (const tx of invalidTransactions) {
201
+ this.logger?.warn(tx[0]._hash)
202
+ }
203
+ }
204
+
193
205
  // Add the valid hydrated transactions to the result set.
194
206
  foundPendingTransactions.push(...validTransactions)
195
207
  }
@@ -0,0 +1,34 @@
1
+ import { creatable, Hash } from '@xylabs/sdk-js'
2
+ import { spanRootAsync } from '@xylabs/telemetry'
3
+ import { Schema } from '@xyo-network/payload-model'
4
+ import {
5
+ SchemasService,
6
+ SchemasStepSummaryContext,
7
+ schemasSummary,
8
+ } from '@xyo-network/xl1-protocol-sdk'
9
+
10
+ import { BaseService } from '../BaseService.ts'
11
+ import { BaseServiceParams } from '../model/index.ts'
12
+
13
+ export interface BaseSchemasServiceParams extends BaseServiceParams {
14
+ context: SchemasStepSummaryContext
15
+ }
16
+
17
+ @creatable()
18
+ export class BaseSchemasService extends BaseService<BaseSchemasServiceParams> implements SchemasService {
19
+ async schema(head: Hash, schema: Schema): Promise<number> {
20
+ return (await this.schemas(head, [schema]))[schema] ?? 0
21
+ }
22
+
23
+ async schemas(head: Hash, schemas: Schema[]): Promise<Partial<Record<Schema, number>>> {
24
+ return await spanRootAsync('transfers', async () => {
25
+ const summary = await schemasSummary(this.params.context)
26
+ const result: Record<Schema, number> = {}
27
+ for (const schema of schemas) {
28
+ const count = summary[schema] ?? 0
29
+ result[schema] = count
30
+ }
31
+ return result
32
+ })
33
+ }
34
+ }
@@ -0,0 +1 @@
1
+ export * from './BaseSchemasService.ts'
@@ -25,6 +25,7 @@ import {
25
25
  isChainIndexingServiceState,
26
26
  readPayloadMapFromStore,
27
27
  StakeIntentService,
28
+ timeBudget,
28
29
  } from '@xyo-network/xl1-protocol-sdk'
29
30
  import { Mutex } from 'async-mutex'
30
31
  import { LRUCache } from 'lru-cache'
@@ -169,34 +170,36 @@ export class XyoStakeIntentService extends BaseService<XyoStakeIntentServicePara
169
170
  }
170
171
 
171
172
  private async recoverState(current: Hash): Promise<void> {
172
- const currentBlock = assertEx(asBlockBoundWitness((await this.chainArchivist.get([current]))?.[0]), () => `Block ${current} not found`)
173
- const currentBlockNum = currentBlock.block
174
- // Find last state before current head (in case of rollback, we indexed past it on an uncle chain, etc.)
175
- const opts: ArchivistNextOptions = { ...DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS }
176
- while (true) {
177
- const predicate = (p: WithStorageMeta<Payload>) => {
178
- const state = asChainIndexingServiceStateWithStorageMeta(p)
179
- return state ? true : false
180
- }
181
- const state = await findFirstMatching(this.stakeIntentStateArchivist, predicate, opts)
182
- if (isChainIndexingServiceState<SerializedIntervalMap>(state)) {
183
- const indexed = (await this.chainArchivist.get([state.endBlockHash]))?.[0]
184
- const indexedBlock = asBlockBoundWitnessWithStorageMeta(indexed)
185
- if (indexedBlock) {
186
- const indexedBlockNum = indexedBlock.block
187
- if (indexedBlockNum <= currentBlockNum) {
188
- const data = state.state as SerializedIntervalMap
189
- this._producers = new IntervalMap(data)
190
- this._lastIndexedBlockHash = indexedBlock._hash
191
- break
192
- }
173
+ return await timeBudget('XyoStakeIntentService.recoverState', console, async () => {
174
+ const currentBlock = assertEx(asBlockBoundWitness((await this.chainArchivist.get([current]))?.[0]), () => `Block ${current} not found`)
175
+ const currentBlockNum = currentBlock.block
176
+ // Find last state before current head (in case of rollback, we indexed past it on an uncle chain, etc.)
177
+ const opts: ArchivistNextOptions = { ...DEFAULT_FIND_FIRST_MATCHING_NEXT_OPTIONS }
178
+ while (true) {
179
+ const predicate = (p: WithStorageMeta<Payload>) => {
180
+ const state = asChainIndexingServiceStateWithStorageMeta(p)
181
+ return state ? true : false
193
182
  }
194
- } else {
183
+ const state = await findFirstMatching(this.stakeIntentStateArchivist, predicate, opts)
184
+ if (isChainIndexingServiceState<SerializedIntervalMap>(state)) {
185
+ const indexed = (await this.chainArchivist.get([state.endBlockHash]))?.[0]
186
+ const indexedBlock = asBlockBoundWitnessWithStorageMeta(indexed)
187
+ if (indexedBlock) {
188
+ const indexedBlockNum = indexedBlock.block
189
+ if (indexedBlockNum <= currentBlockNum) {
190
+ const data = state.state as SerializedIntervalMap
191
+ this._producers = new IntervalMap(data)
192
+ this._lastIndexedBlockHash = indexedBlock._hash
193
+ break
194
+ }
195
+ }
196
+ } else {
195
197
  // No state found, start from genesis
196
- break
198
+ break
199
+ }
200
+ opts.open = true
197
201
  }
198
- opts.open = true
199
- }
202
+ }, 2000, true)
200
203
  }
201
204
 
202
205
  private async updateIndex(displayProgress = false): Promise<void> {
@@ -207,29 +210,31 @@ export class XyoStakeIntentService extends BaseService<XyoStakeIntentServicePara
207
210
  return await this.spanAsync('updateIndex', async () => {
208
211
  const currentHead = await this.chainIterator.head()
209
212
  if (isUndefined(currentHead)) return
210
- const currentHeadHash = await PayloadBuilder.hash(currentHead)
211
- const chainMap = readPayloadMapFromStore<WithStorageMeta<Payload>>(this.chainArchivist)
212
- const result = await analyzeChain({ chainMap }, [new ChainStakeIntentAnalyzer('producer')], currentHeadHash, this._lastIndexedBlockHash)
213
- const signedDeclarations = filterAs(result.find(isChainSummaryStakeIntent)?.intents ?? [], asChainStakeIntent)
214
- if (currentHead.block === undefined) return
215
- const currentHeadBlockNum = currentHead.block
216
- if (displayProgress) this.logger?.log(`Updating index through 0x${currentHeadBlockNum}`)
217
- for (const signedDeclaration of signedDeclarations) {
218
- const { exp, nbf } = signedDeclaration
219
- const start = nbf
220
- const stop = exp
221
- const address = asAddress(signedDeclaration?.from)
222
- if (start !== undefined && stop !== undefined && address !== undefined) {
223
- this._producers.insert(address, start, stop)
213
+ return await timeBudget('XyoStakeIntentService.updateIndex', console, async () => {
214
+ const currentHeadHash = currentHead._hash
215
+ const chainMap = readPayloadMapFromStore<WithStorageMeta<Payload>>(this.chainArchivist)
216
+ const result = await analyzeChain({ chainMap }, [new ChainStakeIntentAnalyzer('producer')], currentHeadHash, this._lastIndexedBlockHash)
217
+ const signedDeclarations = filterAs(result.find(isChainSummaryStakeIntent)?.intents ?? [], asChainStakeIntent)
218
+ if (currentHead.block === undefined) return
219
+ const currentHeadBlockNum = currentHead.block
220
+ if (displayProgress) this.logger?.log(`Updating index through 0x${currentHeadBlockNum}`)
221
+ for (const signedDeclaration of signedDeclarations) {
222
+ const { exp, nbf } = signedDeclaration
223
+ const start = nbf
224
+ const stop = exp
225
+ const address = asAddress(signedDeclaration?.from)
226
+ if (start !== undefined && stop !== undefined && address !== undefined) {
227
+ this._producers.insert(address, start, stop)
228
+ }
224
229
  }
225
- }
226
- /*
230
+ /*
227
231
  if (index % STATE_PERSISTENCE_INTERVAL === 0n) {
228
232
  if (displayProgress) this.logger?.info(`Persisting state at block ${index}`)
229
233
  await this.persistState(await PayloadBuilder.hash(block))
230
234
  }
231
235
  */
232
- this._lastIndexedBlockHash = currentHeadHash
236
+ this._lastIndexedBlockHash = currentHeadHash
237
+ }, 2000, true)
233
238
  })
234
239
  })
235
240
  }
package/src/index.ts CHANGED
@@ -10,6 +10,7 @@ export * from './Election/index.ts'
10
10
  export * from './model/index.ts'
11
11
  export * from './NetworkStakeStepReward/index.ts'
12
12
  export * from './PendingTransactions/index.ts'
13
+ export * from './Schemas/index.ts'
13
14
  export * from './StakeIntent/index.ts'
14
15
  export * from './StepStake/index.ts'
15
16
  export * from './Time/index.ts'