@xyo-network/chain-wrappers 1.19.5 → 1.19.7

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.
@@ -8,7 +8,7 @@ export declare class HydratedBlockWrapper<T extends HydratedBlockWithHashMeta> i
8
8
  protected transactionsCache: HydratedTransactionInstance[];
9
9
  private _parseErrors;
10
10
  private _signatureCache;
11
- protected constructor(context: BaseContext, data: [WithHashMeta<T[0]>, WithHashMeta<T[1][number]>[]]);
11
+ protected constructor(data: [WithHashMeta<T[0]>, WithHashMeta<T[1][number]>[]], context?: BaseContext);
12
12
  get block(): import("@xyo-network/xl1-sdk").XL1BlockNumber;
13
13
  get boundWitness(): WithHashMeta<T[0]>;
14
14
  get chain(): Hex;
@@ -21,7 +21,7 @@ export declare class HydratedBlockWrapper<T extends HydratedBlockWithHashMeta> i
21
21
  get stepHashes(): Hash[];
22
22
  get transactionCount(): number;
23
23
  get transactions(): HydratedTransactionInstance[];
24
- static parse<T extends HydratedBlockWithHashMeta>(context: BaseContext, block: T, validate?: boolean): Promise<HydratedBlockInstance>;
24
+ static parse<T extends HydratedBlockWithHashMeta>(block: T, validate?: boolean): Promise<HydratedBlockInstance>;
25
25
  payload(index: number): WithHashMeta<T[1][number]> | undefined;
26
26
  signature(index: number): SignatureInstance | undefined;
27
27
  transaction(index: number): HydratedTransactionInstance | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"HydratedBlock.d.ts","sourceRoot":"","sources":["../../../src/block/HydratedBlock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AAI/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAC9D,OAAO,KAAK,EACV,oBAAoB,EACpB,WAAW,EACX,qBAAqB,EAAE,yBAAyB,EAAE,2BAA2B,EAAE,iBAAiB,EAEjG,MAAM,sBAAsB,CAAA;AAe7B,qBAAa,oBAAoB,CAAC,CAAC,SAAS,yBAAyB,CAAE,YAAW,qBAAqB,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;IACzJ,IAAI,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAA;IACxD,SAAS,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAK;IAC7D,SAAS,CAAC,OAAO,EAAE,WAAW,CAAA;IAC9B,SAAS,CAAC,iBAAiB,EAAE,2BAA2B,EAAE,CAAK;IAC/D,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,eAAe,CAA0B;IAEjD,SAAS,aAAa,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;IAKpG,IAAI,KAAK,kDAER;IAED,IAAI,YAAY,uBAEf;IAED,IAAI,KAAK,IAAI,GAAG,CAEf;IAED,IAAI,WAAW,YAEd;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,IAAI,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAE7B;IAED,IAAI,MAAM,IAAI,MAAM,CAOnB;IAED,IAAI,cAAc,IAAI,MAAM,CAE3B;IAED,IAAI,UAAU,IAAI,iBAAiB,EAAE,CAEpC;IAED,IAAI,UAAU,IAAI,IAAI,EAAE,CAEvB;IAED,IAAI,gBAAgB,IAAI,MAAM,CAE7B;IAED,IAAI,YAAY,IAAI,2BAA2B,EAAE,CAEhD;WAEY,KAAK,CAAC,CAAC,SAAS,yBAAyB,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,UAAQ,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAKzI,OAAO,CAAC,KAAK,EAAE,MAAM;IAIrB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAIvD,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,2BAA2B,GAAG,SAAS;IAI7D,QAAQ,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;IAI5B,aAAa,CAAC,QAAQ,EAAE;QAAE,cAAc,EAAE,oBAAoB,CAAA;KAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;cAIzE,KAAK,CAAC,QAAQ,UAAQ,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAkB5H"}
1
+ {"version":3,"file":"HydratedBlock.d.ts","sourceRoot":"","sources":["../../../src/block/HydratedBlock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AAI/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAC9D,OAAO,KAAK,EACV,oBAAoB,EACpB,WAAW,EACX,qBAAqB,EAAE,yBAAyB,EAAE,2BAA2B,EAAE,iBAAiB,EAEjG,MAAM,sBAAsB,CAAA;AAe7B,qBAAa,oBAAoB,CAAC,CAAC,SAAS,yBAAyB,CAAE,YAAW,qBAAqB,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;IACzJ,IAAI,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAA;IACxD,SAAS,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAK;IAC7D,SAAS,CAAC,OAAO,EAAE,WAAW,CAAA;IAC9B,SAAS,CAAC,iBAAiB,EAAE,2BAA2B,EAAE,CAAK;IAC/D,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,eAAe,CAA0B;IAEjD,SAAS,aAAa,IAAI,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,WAAW;IAKrG,IAAI,KAAK,kDAER;IAED,IAAI,YAAY,uBAEf;IAED,IAAI,KAAK,IAAI,GAAG,CAEf;IAED,IAAI,WAAW,YAEd;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,IAAI,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAE7B;IAED,IAAI,MAAM,IAAI,MAAM,CAOnB;IAED,IAAI,cAAc,IAAI,MAAM,CAE3B;IAED,IAAI,UAAU,IAAI,iBAAiB,EAAE,CAEpC;IAED,IAAI,UAAU,IAAI,IAAI,EAAE,CAEvB;IAED,IAAI,gBAAgB,IAAI,MAAM,CAE7B;IAED,IAAI,YAAY,IAAI,2BAA2B,EAAE,CAEhD;WAEY,KAAK,CAAC,CAAC,SAAS,yBAAyB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,UAAQ,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAKnH,OAAO,CAAC,KAAK,EAAE,MAAM;IAIrB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAIvD,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,2BAA2B,GAAG,SAAS;IAI7D,QAAQ,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;IAI5B,aAAa,CAAC,QAAQ,EAAE;QAAE,cAAc,EAAE,oBAAoB,CAAA;KAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;cAMzE,KAAK,CAAC,QAAQ,UAAQ,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAkB5H"}
@@ -1,3 +1,2 @@
1
1
  export * from './HydratedBlock.ts';
2
- export * from './IndexedHydratedBlockRangeStore.ts';
3
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/block/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA;AAClC,cAAc,qCAAqC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/block/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA"}
@@ -23,9 +23,11 @@ var HydratedBlockWrapper = class _HydratedBlockWrapper {
23
23
  transactionsCache = [];
24
24
  _parseErrors = [];
25
25
  _signatureCache = [];
26
- constructor(context, data) {
26
+ constructor(data, context) {
27
27
  this.data = data;
28
- this.context = context;
28
+ this.context = context ?? {
29
+ singletons: {}
30
+ };
29
31
  }
30
32
  get block() {
31
33
  return this.data[0].block;
@@ -67,8 +69,8 @@ var HydratedBlockWrapper = class _HydratedBlockWrapper {
67
69
  get transactions() {
68
70
  return this.transactionsCache;
69
71
  }
70
- static async parse(context, block, validate = false) {
71
- const wrapper = new _HydratedBlockWrapper(context, block);
72
+ static async parse(block, validate = false) {
73
+ const wrapper = new _HydratedBlockWrapper(block);
72
74
  return await wrapper.parse(validate);
73
75
  }
74
76
  payload(index) {
@@ -84,7 +86,11 @@ var HydratedBlockWrapper = class _HydratedBlockWrapper {
84
86
  return await validateHydratedBlock(this.context, this.data);
85
87
  }
86
88
  async validateState(services) {
87
- return await validateHydratedBlockState(this.context, this.data, () => this.chain, services);
89
+ return await validateHydratedBlockState({
90
+ ...this.context,
91
+ chainIdAtBlockNumber: /* @__PURE__ */ __name(() => this.chain, "chainIdAtBlockNumber"),
92
+ ...services
93
+ }, this.data);
88
94
  }
89
95
  async parse(validate = false) {
90
96
  const allPayloads = await PayloadBuilder.addStorageMeta(this.data[1]);
@@ -107,163 +113,9 @@ var HydratedBlockWrapper = class _HydratedBlockWrapper {
107
113
  }
108
114
  };
109
115
 
110
- // src/block/IndexedHydratedBlockRangeStore.ts
111
- import { assertEx, BaseEmitter, exists, isDefined } from "@xylabs/sdk-js";
112
- import { asBlockBoundWitness, asBlockBoundWitnessWithStorageMeta, hydrateBlock, readPayloadMapFromStore } from "@xyo-network/xl1-sdk";
113
- import { Semaphore } from "async-mutex";
114
- var BlockNumberIndexSemaphoreLocks = 10;
115
- var IndexedHydratedBlockRangeStore = class _IndexedHydratedBlockRangeStore extends BaseEmitter {
116
- static {
117
- __name(this, "IndexedHydratedBlockRangeStore");
118
- }
119
- _blockNumberIndex = /* @__PURE__ */ new Map();
120
- _blockNumberIndexSemaphore = new Semaphore(BlockNumberIndexSemaphoreLocks);
121
- _firstNumber;
122
- _lastNumber;
123
- constructor(params, firstNumber, lastNumber) {
124
- super(params);
125
- this._firstNumber = firstNumber;
126
- this._lastNumber = lastNumber;
127
- }
128
- get count() {
129
- return this._lastNumber - this._firstNumber + 1;
130
- }
131
- get numberRange() {
132
- return [
133
- this._firstNumber,
134
- this._lastNumber
135
- ];
136
- }
137
- get range() {
138
- return [
139
- this.params.first,
140
- this.params.last
141
- ];
142
- }
143
- static async create(params) {
144
- const firstBlock = asBlockBoundWitness((await params.sourceArchivist.get([
145
- params.first
146
- ])).at(0) ?? (await params.snapshotArchivist.get([
147
- params.first
148
- ])).at(0));
149
- const firstBlockExisting = assertEx(firstBlock, () => "First block not found");
150
- const lastBlock = asBlockBoundWitness((await params.sourceArchivist.get([
151
- params.last
152
- ])).at(0) ?? (await params.snapshotArchivist.get([
153
- params.last
154
- ])).at(0));
155
- const lastBlockExisting = assertEx(lastBlock, () => "Last block not found");
156
- const result = new _IndexedHydratedBlockRangeStore(params, firstBlockExisting.block, lastBlockExisting.block);
157
- result.createSubscriptions();
158
- await result.index();
159
- return result;
160
- }
161
- async first() {
162
- return assertEx(await this.fromHash(this.params.first), () => "First block not found");
163
- }
164
- async fromHash(hash) {
165
- const chainMap = readPayloadMapFromStore(this.params.sourceArchivist);
166
- const snapshotMap = readPayloadMapFromStore(this.params.snapshotArchivist);
167
- const block = await hydrateBlock({
168
- chainMap
169
- }, hash) ?? await hydrateBlock({
170
- chainMap: snapshotMap
171
- }, hash);
172
- if (isDefined(block) && block[0].block <= this._lastNumber && block[0].block >= this._firstNumber) {
173
- return block;
174
- }
175
- }
176
- fromNumber(number) {
177
- const hash = this._blockNumberIndex.get(number);
178
- if (isDefined(hash)) {
179
- return this.fromHash(hash);
180
- }
181
- }
182
- async last() {
183
- return assertEx(await this.fromHash(this.params.last), () => "Last block not found");
184
- }
185
- async next(from, count) {
186
- const nextBlockNumber = from[0].block + 1;
187
- if (nextBlockNumber > this._lastNumber) {
188
- return isDefined(count) ? [] : void 0;
189
- }
190
- if (isDefined(count)) {
191
- if (count === 0) {
192
- return [];
193
- }
194
- const nextBlock = await this.fromNumber(nextBlockNumber);
195
- if (isDefined(nextBlock)) {
196
- return [
197
- nextBlock,
198
- ...await this.next(nextBlock, count - 1)
199
- ].filter(exists);
200
- } else {
201
- if (from[0].block < this._lastNumber) {
202
- throw new Error(`Next block [${nextBlockNumber}] not found, but should be in range`);
203
- }
204
- return [];
205
- }
206
- } else {
207
- return await this.fromNumber(nextBlockNumber);
208
- }
209
- }
210
- async prev(from, count) {
211
- const prevBlockNumber = from[0].block - 1;
212
- if (prevBlockNumber < this._firstNumber) {
213
- return isDefined(count) ? [] : void 0;
214
- }
215
- if (isDefined(count)) {
216
- if (count === 0) {
217
- return [];
218
- }
219
- const prevBlock = await this.fromNumber(prevBlockNumber);
220
- if (isDefined(prevBlock)) {
221
- return [
222
- ...await this.next(prevBlock, count - 1),
223
- prevBlock
224
- ].filter(exists);
225
- } else {
226
- if (from[0].block > this._firstNumber) {
227
- throw new Error(`Prev block [${prevBlockNumber}] not found, but should be in range`);
228
- }
229
- return [];
230
- }
231
- } else {
232
- return await this.fromNumber(prevBlockNumber);
233
- }
234
- }
235
- createSubscriptions() {
236
- this.params.sourceArchivist.on("deleted", async ({ payloads }) => {
237
- await this.params.snapshotArchivist.insert(payloads);
238
- });
239
- }
240
- async index() {
241
- await this._blockNumberIndexSemaphore.acquire(BlockNumberIndexSemaphoreLocks);
242
- try {
243
- this._blockNumberIndex.clear();
244
- let blockToIndex = this.params.last;
245
- let firstFound = false;
246
- while (!firstFound) {
247
- const payload = assertEx((await this.params.sourceArchivist.get([
248
- blockToIndex
249
- ])).at(0), () => "Block payload not found");
250
- const block = assertEx(asBlockBoundWitnessWithStorageMeta(payload), () => "Payload is not a Block");
251
- if (block.block < this._firstNumber || block.block > this._lastNumber) {
252
- throw new Error(`Block [${block.block}] is out of range`);
253
- }
254
- this._blockNumberIndex.set(block.block, block._hash);
255
- firstFound = block.block === this._firstNumber;
256
- }
257
- } finally {
258
- this._blockNumberIndexSemaphore.release(BlockNumberIndexSemaphoreLocks);
259
- }
260
- }
261
- };
262
-
263
116
  // src/index.ts
264
117
  export * from "@xyo-network/xl1-sdk";
265
118
  export {
266
- HydratedBlockWrapper,
267
- IndexedHydratedBlockRangeStore
119
+ HydratedBlockWrapper
268
120
  };
269
121
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/block/HydratedBlock.ts","../../src/block/IndexedHydratedBlockRangeStore.ts","../../src/index.ts"],"sourcesContent":["import type { Hash, Hex } from '@xylabs/sdk-js'\nimport { hexToBigInt } from '@xylabs/sdk-js'\nimport { validateHydratedBlock, validateHydratedBlockState } from '@xyo-network/chain-validation'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport type { WithHashMeta } from '@xyo-network/payload-model'\nimport type {\n AccountBalanceViewer,\n BaseContext,\n HydratedBlockInstance, HydratedBlockWithHashMeta, HydratedTransactionInstance, SignatureInstance,\n SignedHydratedTransactionWithStorageMeta, Transfer,\n} from '@xyo-network/xl1-sdk'\nimport {\n createSignatureWrappers, HydratedTransactionWrapper,\n isSignedTransactionBoundWitnessWithStorageMeta,\n isTransfer, XYO_ZERO_ADDRESS,\n} from '@xyo-network/xl1-sdk'\n\nconst sumTransfers = (payload: Transfer) => {\n let total = 0n\n for (let i of Object.values(payload.transfers)) {\n total += hexToBigInt(i ?? '00' as Hex)\n }\n return total\n}\n\nexport class HydratedBlockWrapper<T extends HydratedBlockWithHashMeta> implements HydratedBlockInstance<[WithHashMeta<T[0]>, WithHashMeta<T[1][number]>[]]> {\n data: [WithHashMeta<T[0]>, WithHashMeta<T[1][number]>[]]\n protected allPayloadsCache: WithHashMeta<T[1][number]>[] = []\n protected context: BaseContext\n protected transactionsCache: HydratedTransactionInstance[] = []\n private _parseErrors: Error[] = []\n private _signatureCache: SignatureInstance[] = []\n\n protected constructor(context: BaseContext, data: [WithHashMeta<T[0]>, WithHashMeta<T[1][number]>[]]) {\n this.data = data\n this.context = context\n }\n\n get block() {\n return this.data[0].block\n }\n\n get boundWitness() {\n return this.data[0]\n }\n\n get chain(): Hex {\n return this.data[0].chain\n }\n\n get parseErrors() {\n return this._parseErrors\n }\n\n get payloadCount(): number {\n return this.allPayloadsCache.length\n }\n\n get payloads(): T[1][number][] {\n return [...this.allPayloadsCache]\n }\n\n get reward(): bigint {\n return this.allPayloadsCache.reduce((acc: bigint, payload) => acc + (\n isTransfer(payload)\n ? payload.from === XYO_ZERO_ADDRESS\n ? sumTransfers(payload)\n : 0n\n : 0n), 0n)\n }\n\n get signatureCount(): number {\n return this._signatureCache.length\n }\n\n get signatures(): SignatureInstance[] {\n return [...this._signatureCache]\n }\n\n get stepHashes(): Hash[] {\n return this.data[0].step_hashes ?? []\n }\n\n get transactionCount(): number {\n return this.transactionsCache.length\n }\n\n get transactions(): HydratedTransactionInstance[] {\n return this.transactionsCache\n }\n\n static async parse<T extends HydratedBlockWithHashMeta>(context: BaseContext, block: T, validate = false): Promise<HydratedBlockInstance> {\n const wrapper = new HydratedBlockWrapper(context, block)\n return await wrapper.parse(validate)\n }\n\n payload(index: number) {\n return this.data[1].at(index)\n }\n\n signature(index: number): SignatureInstance | undefined {\n return this._signatureCache[index]\n }\n\n transaction(index: number): HydratedTransactionInstance | undefined {\n return this.transactionsCache.at(index)\n }\n\n async validate(): Promise<Error[]> {\n return await validateHydratedBlock(this.context, this.data)\n }\n\n async validateState(services: { accountBalance: AccountBalanceViewer }): Promise<Error[]> {\n return await validateHydratedBlockState(this.context, this.data, () => this.chain, services)\n }\n\n protected async parse(validate = false): Promise<HydratedBlockInstance<[WithHashMeta<T[0]>, WithHashMeta<T[1][number]>[]]>> {\n const allPayloads = await PayloadBuilder.addStorageMeta(this.data[1])\n for (const payload of allPayloads) {\n if (isSignedTransactionBoundWitnessWithStorageMeta(payload)) {\n const hydratedTransaction: SignedHydratedTransactionWithStorageMeta = [payload, allPayloads.filter(\n p => payload.payload_hashes.includes(p._hash) || payload.payload_hashes.includes(p._dataHash),\n )]\n this.transactionsCache.push(await HydratedTransactionWrapper.parse(hydratedTransaction))\n } else {\n this.allPayloadsCache.push(payload)\n }\n }\n this._signatureCache = await createSignatureWrappers(this.data[0])\n if (validate) {\n this._parseErrors = await this.validate()\n }\n return this\n }\n}\n","import type {\n BaseParams, EmptyObject, Hash, Promisable,\n} from '@xylabs/sdk-js'\nimport {\n assertEx, BaseEmitter, exists, isDefined,\n} from '@xylabs/sdk-js'\nimport type { ArchivistInstance } from '@xyo-network/archivist-model'\nimport type { Payload, WithStorageMeta } from '@xyo-network/payload-model'\nimport {\n asBlockBoundWitness, asBlockBoundWitnessWithStorageMeta, type BlockWindowInstance, hydrateBlock, type HydratedBlock,\n readPayloadMapFromStore,\n} from '@xyo-network/xl1-sdk'\nimport { Semaphore } from 'async-mutex'\n\nexport type HydratedBlockStoreParams<TAdditionalParams extends EmptyObject = EmptyObject> = BaseParams<{\n sourceArchivist: ArchivistInstance\n} & TAdditionalParams>\n\nexport interface HydratedBlockStoreInstance {\n fromHash(hash: Hash): Promisable<HydratedBlock | undefined>\n}\n\nexport interface IndexedHydratedBlockStoreInstance extends HydratedBlockStoreInstance {\n fromNumber(number: number): Promisable<HydratedBlock | undefined>\n}\n\nexport interface HydratedBlockRangeStoreParams extends HydratedBlockStoreParams<{\n first: Hash\n last: Hash\n snapshotArchivist: ArchivistInstance\n}> {}\n\nexport interface IndexedHydratedBlockRangeStoreInstance extends BlockWindowInstance, IndexedHydratedBlockStoreInstance {\n first(): Promisable<HydratedBlock>\n last(): Promisable<HydratedBlock>\n next(from: HydratedBlock): Promisable<HydratedBlock | undefined>\n next(from: HydratedBlock, count: number): Promisable<HydratedBlock[]>\n prev(from: HydratedBlock): Promisable<HydratedBlock | undefined>\n prev(from: HydratedBlock, count: number): Promisable<HydratedBlock[]>\n}\n\nconst BlockNumberIndexSemaphoreLocks = 10 as const\n\n// TODO: Allow/Require source/snapshot archivist to be BlockStores instead\nexport class IndexedHydratedBlockRangeStore extends BaseEmitter<HydratedBlockRangeStoreParams> implements IndexedHydratedBlockRangeStoreInstance {\n private _blockNumberIndex: Map<number, Hash> = new Map()\n private _blockNumberIndexSemaphore = new Semaphore(BlockNumberIndexSemaphoreLocks)\n private _firstNumber: number\n private _lastNumber: number\n\n protected constructor(params: HydratedBlockRangeStoreParams, firstNumber: number, lastNumber: number) {\n super(params)\n this._firstNumber = firstNumber\n this._lastNumber = lastNumber\n }\n\n get count(): number {\n return this._lastNumber - this._firstNumber + 1\n }\n\n get numberRange(): [number, number] {\n return [this._firstNumber, this._lastNumber]\n }\n\n get range(): [Hash, Hash] {\n return [this.params.first, this.params.last]\n }\n\n static async create(params: HydratedBlockRangeStoreParams): Promise<IndexedHydratedBlockRangeStore> {\n const firstBlock = asBlockBoundWitness((await params.sourceArchivist.get([params.first])).at(0)\n ?? (await params.snapshotArchivist.get([params.first])).at(0))\n const firstBlockExisting = assertEx(firstBlock, () => 'First block not found')\n\n const lastBlock = asBlockBoundWitness((await params.sourceArchivist.get([params.last])).at(0)\n ?? (await params.snapshotArchivist.get([params.last])).at(0))\n const lastBlockExisting = assertEx(lastBlock, () => 'Last block not found')\n\n // getting the block numbers here since can not get them in the constructor\n const result = new IndexedHydratedBlockRangeStore(params, firstBlockExisting.block, lastBlockExisting.block)\n result.createSubscriptions()\n await result.index()\n return result\n }\n\n async first(): Promise<HydratedBlock> {\n return assertEx(await this.fromHash(this.params.first), () => 'First block not found')\n }\n\n async fromHash(hash: Hash): Promise<HydratedBlock | undefined> {\n const chainMap = readPayloadMapFromStore<WithStorageMeta<Payload>>(this.params.sourceArchivist)\n const snapshotMap = readPayloadMapFromStore<WithStorageMeta<Payload>>(this.params.snapshotArchivist)\n const block = (await hydrateBlock({ chainMap }, hash))\n ?? (await hydrateBlock({ chainMap: snapshotMap }, hash))\n if (isDefined(block) && (block[0].block <= this._lastNumber && block[0].block >= this._firstNumber)) {\n return block\n }\n }\n\n fromNumber(number: number): Promisable<HydratedBlock | undefined> {\n const hash = this._blockNumberIndex.get(number)\n if (isDefined(hash)) {\n return this.fromHash(hash)\n }\n }\n\n async last(): Promise<HydratedBlock> {\n return assertEx(await this.fromHash(this.params.last), () => 'Last block not found')\n }\n\n async next(from: HydratedBlock): Promise<HydratedBlock | undefined>\n async next(from: HydratedBlock, count: number): Promise<HydratedBlock[]>\n async next(from: HydratedBlock, count?: number): Promise<HydratedBlock | HydratedBlock[] | undefined> {\n const nextBlockNumber = from[0].block + 1\n if (nextBlockNumber > this._lastNumber) {\n return isDefined(count) ? [] : undefined\n }\n if (isDefined(count)) {\n if (count === 0) {\n return []\n }\n const nextBlock = await this.fromNumber(nextBlockNumber)\n\n if (isDefined(nextBlock)) {\n return [nextBlock, ...await this.next(nextBlock, count - 1)].filter(exists)\n } else {\n if (from[0].block < this._lastNumber) {\n throw new Error(`Next block [${nextBlockNumber}] not found, but should be in range`)\n }\n return []\n }\n } else {\n return await this.fromNumber(nextBlockNumber)\n }\n }\n\n async prev(from: HydratedBlock): Promise<HydratedBlock | undefined>\n async prev(from: HydratedBlock, count: number): Promise<HydratedBlock[]>\n async prev(from: HydratedBlock, count?: number): Promise<HydratedBlock | HydratedBlock[] | undefined> {\n const prevBlockNumber = from[0].block - 1\n if (prevBlockNumber < this._firstNumber) {\n return isDefined(count) ? [] : undefined\n }\n if (isDefined(count)) {\n if (count === 0) {\n return []\n }\n const prevBlock = await this.fromNumber(prevBlockNumber)\n if (isDefined(prevBlock)) {\n return [...await this.next(prevBlock, count - 1), prevBlock].filter(exists)\n } else {\n if (from[0].block > this._firstNumber) {\n throw new Error(`Prev block [${prevBlockNumber}] not found, but should be in range`)\n }\n return []\n }\n } else {\n return await this.fromNumber(prevBlockNumber)\n }\n }\n\n private createSubscriptions(): void {\n // we monitor deletes so that we can keep them if we need them for the window\n this.params.sourceArchivist.on('deleted', async ({ payloads }) => {\n await this.params.snapshotArchivist.insert(payloads)\n })\n }\n\n private async index() {\n // get all the locks (make exclusive)\n await this._blockNumberIndexSemaphore.acquire(BlockNumberIndexSemaphoreLocks)\n try {\n this._blockNumberIndex.clear()\n let blockToIndex: Hash = this.params.last\n let firstFound = false\n while (!firstFound) {\n const payload = assertEx((await this.params.sourceArchivist.get([blockToIndex])).at(0), () => 'Block payload not found')\n const block = assertEx(asBlockBoundWitnessWithStorageMeta(payload), () => 'Payload is not a Block')\n if (block.block < this._firstNumber || block.block > this._lastNumber) {\n throw new Error(`Block [${block.block}] is out of range`)\n }\n this._blockNumberIndex.set(block.block, block._hash)\n firstFound = block.block === this._firstNumber\n }\n } finally {\n this._blockNumberIndexSemaphore.release(BlockNumberIndexSemaphoreLocks)\n }\n }\n}\n","export * from './block/index.ts'\nexport * from '@xyo-network/xl1-sdk'\n"],"mappings":"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","names":["hexToBigInt","validateHydratedBlock","validateHydratedBlockState","PayloadBuilder","createSignatureWrappers","HydratedTransactionWrapper","isSignedTransactionBoundWitnessWithStorageMeta","isTransfer","XYO_ZERO_ADDRESS","sumTransfers","payload","total","i","Object","values","transfers","hexToBigInt","HydratedBlockWrapper","data","allPayloadsCache","context","transactionsCache","_parseErrors","_signatureCache","block","boundWitness","chain","parseErrors","payloadCount","length","payloads","reward","reduce","acc","isTransfer","from","XYO_ZERO_ADDRESS","signatureCount","signatures","stepHashes","step_hashes","transactionCount","transactions","parse","validate","wrapper","index","at","signature","transaction","validateHydratedBlock","validateState","services","validateHydratedBlockState","allPayloads","PayloadBuilder","addStorageMeta","isSignedTransactionBoundWitnessWithStorageMeta","hydratedTransaction","filter","p","payload_hashes","includes","_hash","_dataHash","push","HydratedTransactionWrapper","createSignatureWrappers","assertEx","BaseEmitter","exists","isDefined","asBlockBoundWitness","asBlockBoundWitnessWithStorageMeta","hydrateBlock","readPayloadMapFromStore","Semaphore","BlockNumberIndexSemaphoreLocks","IndexedHydratedBlockRangeStore","BaseEmitter","_blockNumberIndex","Map","_blockNumberIndexSemaphore","Semaphore","_firstNumber","_lastNumber","params","firstNumber","lastNumber","count","numberRange","range","first","last","create","firstBlock","asBlockBoundWitness","sourceArchivist","get","at","snapshotArchivist","firstBlockExisting","assertEx","lastBlock","lastBlockExisting","result","block","createSubscriptions","index","fromHash","hash","chainMap","readPayloadMapFromStore","snapshotMap","hydrateBlock","isDefined","fromNumber","number","next","from","nextBlockNumber","undefined","nextBlock","filter","exists","Error","prev","prevBlockNumber","prevBlock","on","payloads","insert","acquire","clear","blockToIndex","firstFound","payload","asBlockBoundWitnessWithStorageMeta","set","_hash","release"]}
1
+ {"version":3,"sources":["../../src/block/HydratedBlock.ts","../../src/index.ts"],"sourcesContent":["import type { Hash, Hex } from '@xylabs/sdk-js'\nimport { hexToBigInt } from '@xylabs/sdk-js'\nimport { validateHydratedBlock, validateHydratedBlockState } from '@xyo-network/chain-validation'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport type { WithHashMeta } from '@xyo-network/payload-model'\nimport type {\n AccountBalanceViewer,\n BaseContext,\n HydratedBlockInstance, HydratedBlockWithHashMeta, HydratedTransactionInstance, SignatureInstance,\n SignedHydratedTransactionWithStorageMeta, Transfer,\n} from '@xyo-network/xl1-sdk'\nimport {\n createSignatureWrappers, HydratedTransactionWrapper,\n isSignedTransactionBoundWitnessWithStorageMeta,\n isTransfer, XYO_ZERO_ADDRESS,\n} from '@xyo-network/xl1-sdk'\n\nconst sumTransfers = (payload: Transfer) => {\n let total = 0n\n for (let i of Object.values(payload.transfers)) {\n total += hexToBigInt(i ?? '00' as Hex)\n }\n return total\n}\n\nexport class HydratedBlockWrapper<T extends HydratedBlockWithHashMeta> implements HydratedBlockInstance<[WithHashMeta<T[0]>, WithHashMeta<T[1][number]>[]]> {\n data: [WithHashMeta<T[0]>, WithHashMeta<T[1][number]>[]]\n protected allPayloadsCache: WithHashMeta<T[1][number]>[] = []\n protected context: BaseContext\n protected transactionsCache: HydratedTransactionInstance[] = []\n private _parseErrors: Error[] = []\n private _signatureCache: SignatureInstance[] = []\n\n protected constructor(data: [WithHashMeta<T[0]>, WithHashMeta<T[1][number]>[]], context?: BaseContext) {\n this.data = data\n this.context = context ?? { singletons: {} }\n }\n\n get block() {\n return this.data[0].block\n }\n\n get boundWitness() {\n return this.data[0]\n }\n\n get chain(): Hex {\n return this.data[0].chain\n }\n\n get parseErrors() {\n return this._parseErrors\n }\n\n get payloadCount(): number {\n return this.allPayloadsCache.length\n }\n\n get payloads(): T[1][number][] {\n return [...this.allPayloadsCache]\n }\n\n get reward(): bigint {\n return this.allPayloadsCache.reduce((acc: bigint, payload) => acc + (\n isTransfer(payload)\n ? payload.from === XYO_ZERO_ADDRESS\n ? sumTransfers(payload)\n : 0n\n : 0n), 0n)\n }\n\n get signatureCount(): number {\n return this._signatureCache.length\n }\n\n get signatures(): SignatureInstance[] {\n return [...this._signatureCache]\n }\n\n get stepHashes(): Hash[] {\n return this.data[0].step_hashes ?? []\n }\n\n get transactionCount(): number {\n return this.transactionsCache.length\n }\n\n get transactions(): HydratedTransactionInstance[] {\n return this.transactionsCache\n }\n\n static async parse<T extends HydratedBlockWithHashMeta>(block: T, validate = false): Promise<HydratedBlockInstance> {\n const wrapper = new HydratedBlockWrapper(block)\n return await wrapper.parse(validate)\n }\n\n payload(index: number) {\n return this.data[1].at(index)\n }\n\n signature(index: number): SignatureInstance | undefined {\n return this._signatureCache[index]\n }\n\n transaction(index: number): HydratedTransactionInstance | undefined {\n return this.transactionsCache.at(index)\n }\n\n async validate(): Promise<Error[]> {\n return await validateHydratedBlock(this.context, this.data)\n }\n\n async validateState(services: { accountBalance: AccountBalanceViewer }): Promise<Error[]> {\n return await validateHydratedBlockState({\n ...this.context, chainIdAtBlockNumber: () => this.chain, ...services,\n }, this.data)\n }\n\n protected async parse(validate = false): Promise<HydratedBlockInstance<[WithHashMeta<T[0]>, WithHashMeta<T[1][number]>[]]>> {\n const allPayloads = await PayloadBuilder.addStorageMeta(this.data[1])\n for (const payload of allPayloads) {\n if (isSignedTransactionBoundWitnessWithStorageMeta(payload)) {\n const hydratedTransaction: SignedHydratedTransactionWithStorageMeta = [payload, allPayloads.filter(\n p => payload.payload_hashes.includes(p._hash) || payload.payload_hashes.includes(p._dataHash),\n )]\n this.transactionsCache.push(await HydratedTransactionWrapper.parse(hydratedTransaction))\n } else {\n this.allPayloadsCache.push(payload)\n }\n }\n this._signatureCache = await createSignatureWrappers(this.data[0])\n if (validate) {\n this._parseErrors = await this.validate()\n }\n return this\n }\n}\n","export * from './block/index.ts'\nexport * from '@xyo-network/xl1-sdk'\n"],"mappings":"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","names":["hexToBigInt","validateHydratedBlock","validateHydratedBlockState","PayloadBuilder","createSignatureWrappers","HydratedTransactionWrapper","isSignedTransactionBoundWitnessWithStorageMeta","isTransfer","XYO_ZERO_ADDRESS","sumTransfers","payload","total","i","Object","values","transfers","hexToBigInt","HydratedBlockWrapper","data","allPayloadsCache","context","transactionsCache","_parseErrors","_signatureCache","singletons","block","boundWitness","chain","parseErrors","payloadCount","length","payloads","reward","reduce","acc","isTransfer","from","XYO_ZERO_ADDRESS","signatureCount","signatures","stepHashes","step_hashes","transactionCount","transactions","parse","validate","wrapper","index","at","signature","transaction","validateHydratedBlock","validateState","services","validateHydratedBlockState","chainIdAtBlockNumber","allPayloads","PayloadBuilder","addStorageMeta","isSignedTransactionBoundWitnessWithStorageMeta","hydratedTransaction","filter","p","payload_hashes","includes","_hash","_dataHash","push","HydratedTransactionWrapper","createSignatureWrappers"]}
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-wrappers",
4
- "version": "1.19.5",
4
+ "version": "1.19.7",
5
5
  "description": "XYO Layer One SDK Wrappers",
6
6
  "homepage": "https://xylabs.com",
7
7
  "bugs": {
@@ -39,16 +39,15 @@
39
39
  "!**/*.test.*"
40
40
  ],
41
41
  "dependencies": {
42
- "@xylabs/sdk-js": "~5.0.64",
42
+ "@xylabs/sdk-js": "~5.0.65",
43
43
  "@xyo-network/archivist-model": "~5.3.2",
44
- "@xyo-network/chain-validation": "~1.19.5",
44
+ "@xyo-network/chain-validation": "~1.19.7",
45
45
  "@xyo-network/payload-builder": "~5.3.2",
46
46
  "@xyo-network/payload-model": "~5.3.2",
47
- "@xyo-network/xl1-sdk": "~1.21.10",
48
- "async-mutex": "~0.5.0"
47
+ "@xyo-network/xl1-sdk": "~1.22.30"
49
48
  },
50
49
  "devDependencies": {
51
- "@types/node": "~25.1.0",
50
+ "@types/node": "~25.2.1",
52
51
  "@xylabs/ts-scripts-yarn3": "~7.3.2",
53
52
  "@xylabs/tsconfig": "~7.3.2",
54
53
  "eslint": "^9.39.2",
@@ -31,9 +31,9 @@ export class HydratedBlockWrapper<T extends HydratedBlockWithHashMeta> implement
31
31
  private _parseErrors: Error[] = []
32
32
  private _signatureCache: SignatureInstance[] = []
33
33
 
34
- protected constructor(context: BaseContext, data: [WithHashMeta<T[0]>, WithHashMeta<T[1][number]>[]]) {
34
+ protected constructor(data: [WithHashMeta<T[0]>, WithHashMeta<T[1][number]>[]], context?: BaseContext) {
35
35
  this.data = data
36
- this.context = context
36
+ this.context = context ?? { singletons: {} }
37
37
  }
38
38
 
39
39
  get block() {
@@ -89,8 +89,8 @@ export class HydratedBlockWrapper<T extends HydratedBlockWithHashMeta> implement
89
89
  return this.transactionsCache
90
90
  }
91
91
 
92
- static async parse<T extends HydratedBlockWithHashMeta>(context: BaseContext, block: T, validate = false): Promise<HydratedBlockInstance> {
93
- const wrapper = new HydratedBlockWrapper(context, block)
92
+ static async parse<T extends HydratedBlockWithHashMeta>(block: T, validate = false): Promise<HydratedBlockInstance> {
93
+ const wrapper = new HydratedBlockWrapper(block)
94
94
  return await wrapper.parse(validate)
95
95
  }
96
96
 
@@ -111,7 +111,9 @@ export class HydratedBlockWrapper<T extends HydratedBlockWithHashMeta> implement
111
111
  }
112
112
 
113
113
  async validateState(services: { accountBalance: AccountBalanceViewer }): Promise<Error[]> {
114
- return await validateHydratedBlockState(this.context, this.data, () => this.chain, services)
114
+ return await validateHydratedBlockState({
115
+ ...this.context, chainIdAtBlockNumber: () => this.chain, ...services,
116
+ }, this.data)
115
117
  }
116
118
 
117
119
  protected async parse(validate = false): Promise<HydratedBlockInstance<[WithHashMeta<T[0]>, WithHashMeta<T[1][number]>[]]>> {
@@ -1,2 +1 @@
1
1
  export * from './HydratedBlock.ts'
2
- export * from './IndexedHydratedBlockRangeStore.ts'
@@ -1,49 +0,0 @@
1
- import type { BaseParams, EmptyObject, Hash, Promisable } from '@xylabs/sdk-js';
2
- import { BaseEmitter } from '@xylabs/sdk-js';
3
- import type { ArchivistInstance } from '@xyo-network/archivist-model';
4
- import { type BlockWindowInstance, type HydratedBlock } from '@xyo-network/xl1-sdk';
5
- export type HydratedBlockStoreParams<TAdditionalParams extends EmptyObject = EmptyObject> = BaseParams<{
6
- sourceArchivist: ArchivistInstance;
7
- } & TAdditionalParams>;
8
- export interface HydratedBlockStoreInstance {
9
- fromHash(hash: Hash): Promisable<HydratedBlock | undefined>;
10
- }
11
- export interface IndexedHydratedBlockStoreInstance extends HydratedBlockStoreInstance {
12
- fromNumber(number: number): Promisable<HydratedBlock | undefined>;
13
- }
14
- export interface HydratedBlockRangeStoreParams extends HydratedBlockStoreParams<{
15
- first: Hash;
16
- last: Hash;
17
- snapshotArchivist: ArchivistInstance;
18
- }> {
19
- }
20
- export interface IndexedHydratedBlockRangeStoreInstance extends BlockWindowInstance, IndexedHydratedBlockStoreInstance {
21
- first(): Promisable<HydratedBlock>;
22
- last(): Promisable<HydratedBlock>;
23
- next(from: HydratedBlock): Promisable<HydratedBlock | undefined>;
24
- next(from: HydratedBlock, count: number): Promisable<HydratedBlock[]>;
25
- prev(from: HydratedBlock): Promisable<HydratedBlock | undefined>;
26
- prev(from: HydratedBlock, count: number): Promisable<HydratedBlock[]>;
27
- }
28
- export declare class IndexedHydratedBlockRangeStore extends BaseEmitter<HydratedBlockRangeStoreParams> implements IndexedHydratedBlockRangeStoreInstance {
29
- private _blockNumberIndex;
30
- private _blockNumberIndexSemaphore;
31
- private _firstNumber;
32
- private _lastNumber;
33
- protected constructor(params: HydratedBlockRangeStoreParams, firstNumber: number, lastNumber: number);
34
- get count(): number;
35
- get numberRange(): [number, number];
36
- get range(): [Hash, Hash];
37
- static create(params: HydratedBlockRangeStoreParams): Promise<IndexedHydratedBlockRangeStore>;
38
- first(): Promise<HydratedBlock>;
39
- fromHash(hash: Hash): Promise<HydratedBlock | undefined>;
40
- fromNumber(number: number): Promisable<HydratedBlock | undefined>;
41
- last(): Promise<HydratedBlock>;
42
- next(from: HydratedBlock): Promise<HydratedBlock | undefined>;
43
- next(from: HydratedBlock, count: number): Promise<HydratedBlock[]>;
44
- prev(from: HydratedBlock): Promise<HydratedBlock | undefined>;
45
- prev(from: HydratedBlock, count: number): Promise<HydratedBlock[]>;
46
- private createSubscriptions;
47
- private index;
48
- }
49
- //# sourceMappingURL=IndexedHydratedBlockRangeStore.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"IndexedHydratedBlockRangeStore.d.ts","sourceRoot":"","sources":["../../../src/block/IndexedHydratedBlockRangeStore.ts"],"names":[],"mappings":"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"}
@@ -1,188 +0,0 @@
1
- import type {
2
- BaseParams, EmptyObject, Hash, Promisable,
3
- } from '@xylabs/sdk-js'
4
- import {
5
- assertEx, BaseEmitter, exists, isDefined,
6
- } from '@xylabs/sdk-js'
7
- import type { ArchivistInstance } from '@xyo-network/archivist-model'
8
- import type { Payload, WithStorageMeta } from '@xyo-network/payload-model'
9
- import {
10
- asBlockBoundWitness, asBlockBoundWitnessWithStorageMeta, type BlockWindowInstance, hydrateBlock, type HydratedBlock,
11
- readPayloadMapFromStore,
12
- } from '@xyo-network/xl1-sdk'
13
- import { Semaphore } from 'async-mutex'
14
-
15
- export type HydratedBlockStoreParams<TAdditionalParams extends EmptyObject = EmptyObject> = BaseParams<{
16
- sourceArchivist: ArchivistInstance
17
- } & TAdditionalParams>
18
-
19
- export interface HydratedBlockStoreInstance {
20
- fromHash(hash: Hash): Promisable<HydratedBlock | undefined>
21
- }
22
-
23
- export interface IndexedHydratedBlockStoreInstance extends HydratedBlockStoreInstance {
24
- fromNumber(number: number): Promisable<HydratedBlock | undefined>
25
- }
26
-
27
- export interface HydratedBlockRangeStoreParams extends HydratedBlockStoreParams<{
28
- first: Hash
29
- last: Hash
30
- snapshotArchivist: ArchivistInstance
31
- }> {}
32
-
33
- export interface IndexedHydratedBlockRangeStoreInstance extends BlockWindowInstance, IndexedHydratedBlockStoreInstance {
34
- first(): Promisable<HydratedBlock>
35
- last(): Promisable<HydratedBlock>
36
- next(from: HydratedBlock): Promisable<HydratedBlock | undefined>
37
- next(from: HydratedBlock, count: number): Promisable<HydratedBlock[]>
38
- prev(from: HydratedBlock): Promisable<HydratedBlock | undefined>
39
- prev(from: HydratedBlock, count: number): Promisable<HydratedBlock[]>
40
- }
41
-
42
- const BlockNumberIndexSemaphoreLocks = 10 as const
43
-
44
- // TODO: Allow/Require source/snapshot archivist to be BlockStores instead
45
- export class IndexedHydratedBlockRangeStore extends BaseEmitter<HydratedBlockRangeStoreParams> implements IndexedHydratedBlockRangeStoreInstance {
46
- private _blockNumberIndex: Map<number, Hash> = new Map()
47
- private _blockNumberIndexSemaphore = new Semaphore(BlockNumberIndexSemaphoreLocks)
48
- private _firstNumber: number
49
- private _lastNumber: number
50
-
51
- protected constructor(params: HydratedBlockRangeStoreParams, firstNumber: number, lastNumber: number) {
52
- super(params)
53
- this._firstNumber = firstNumber
54
- this._lastNumber = lastNumber
55
- }
56
-
57
- get count(): number {
58
- return this._lastNumber - this._firstNumber + 1
59
- }
60
-
61
- get numberRange(): [number, number] {
62
- return [this._firstNumber, this._lastNumber]
63
- }
64
-
65
- get range(): [Hash, Hash] {
66
- return [this.params.first, this.params.last]
67
- }
68
-
69
- static async create(params: HydratedBlockRangeStoreParams): Promise<IndexedHydratedBlockRangeStore> {
70
- const firstBlock = asBlockBoundWitness((await params.sourceArchivist.get([params.first])).at(0)
71
- ?? (await params.snapshotArchivist.get([params.first])).at(0))
72
- const firstBlockExisting = assertEx(firstBlock, () => 'First block not found')
73
-
74
- const lastBlock = asBlockBoundWitness((await params.sourceArchivist.get([params.last])).at(0)
75
- ?? (await params.snapshotArchivist.get([params.last])).at(0))
76
- const lastBlockExisting = assertEx(lastBlock, () => 'Last block not found')
77
-
78
- // getting the block numbers here since can not get them in the constructor
79
- const result = new IndexedHydratedBlockRangeStore(params, firstBlockExisting.block, lastBlockExisting.block)
80
- result.createSubscriptions()
81
- await result.index()
82
- return result
83
- }
84
-
85
- async first(): Promise<HydratedBlock> {
86
- return assertEx(await this.fromHash(this.params.first), () => 'First block not found')
87
- }
88
-
89
- async fromHash(hash: Hash): Promise<HydratedBlock | undefined> {
90
- const chainMap = readPayloadMapFromStore<WithStorageMeta<Payload>>(this.params.sourceArchivist)
91
- const snapshotMap = readPayloadMapFromStore<WithStorageMeta<Payload>>(this.params.snapshotArchivist)
92
- const block = (await hydrateBlock({ chainMap }, hash))
93
- ?? (await hydrateBlock({ chainMap: snapshotMap }, hash))
94
- if (isDefined(block) && (block[0].block <= this._lastNumber && block[0].block >= this._firstNumber)) {
95
- return block
96
- }
97
- }
98
-
99
- fromNumber(number: number): Promisable<HydratedBlock | undefined> {
100
- const hash = this._blockNumberIndex.get(number)
101
- if (isDefined(hash)) {
102
- return this.fromHash(hash)
103
- }
104
- }
105
-
106
- async last(): Promise<HydratedBlock> {
107
- return assertEx(await this.fromHash(this.params.last), () => 'Last block not found')
108
- }
109
-
110
- async next(from: HydratedBlock): Promise<HydratedBlock | undefined>
111
- async next(from: HydratedBlock, count: number): Promise<HydratedBlock[]>
112
- async next(from: HydratedBlock, count?: number): Promise<HydratedBlock | HydratedBlock[] | undefined> {
113
- const nextBlockNumber = from[0].block + 1
114
- if (nextBlockNumber > this._lastNumber) {
115
- return isDefined(count) ? [] : undefined
116
- }
117
- if (isDefined(count)) {
118
- if (count === 0) {
119
- return []
120
- }
121
- const nextBlock = await this.fromNumber(nextBlockNumber)
122
-
123
- if (isDefined(nextBlock)) {
124
- return [nextBlock, ...await this.next(nextBlock, count - 1)].filter(exists)
125
- } else {
126
- if (from[0].block < this._lastNumber) {
127
- throw new Error(`Next block [${nextBlockNumber}] not found, but should be in range`)
128
- }
129
- return []
130
- }
131
- } else {
132
- return await this.fromNumber(nextBlockNumber)
133
- }
134
- }
135
-
136
- async prev(from: HydratedBlock): Promise<HydratedBlock | undefined>
137
- async prev(from: HydratedBlock, count: number): Promise<HydratedBlock[]>
138
- async prev(from: HydratedBlock, count?: number): Promise<HydratedBlock | HydratedBlock[] | undefined> {
139
- const prevBlockNumber = from[0].block - 1
140
- if (prevBlockNumber < this._firstNumber) {
141
- return isDefined(count) ? [] : undefined
142
- }
143
- if (isDefined(count)) {
144
- if (count === 0) {
145
- return []
146
- }
147
- const prevBlock = await this.fromNumber(prevBlockNumber)
148
- if (isDefined(prevBlock)) {
149
- return [...await this.next(prevBlock, count - 1), prevBlock].filter(exists)
150
- } else {
151
- if (from[0].block > this._firstNumber) {
152
- throw new Error(`Prev block [${prevBlockNumber}] not found, but should be in range`)
153
- }
154
- return []
155
- }
156
- } else {
157
- return await this.fromNumber(prevBlockNumber)
158
- }
159
- }
160
-
161
- private createSubscriptions(): void {
162
- // we monitor deletes so that we can keep them if we need them for the window
163
- this.params.sourceArchivist.on('deleted', async ({ payloads }) => {
164
- await this.params.snapshotArchivist.insert(payloads)
165
- })
166
- }
167
-
168
- private async index() {
169
- // get all the locks (make exclusive)
170
- await this._blockNumberIndexSemaphore.acquire(BlockNumberIndexSemaphoreLocks)
171
- try {
172
- this._blockNumberIndex.clear()
173
- let blockToIndex: Hash = this.params.last
174
- let firstFound = false
175
- while (!firstFound) {
176
- const payload = assertEx((await this.params.sourceArchivist.get([blockToIndex])).at(0), () => 'Block payload not found')
177
- const block = assertEx(asBlockBoundWitnessWithStorageMeta(payload), () => 'Payload is not a Block')
178
- if (block.block < this._firstNumber || block.block > this._lastNumber) {
179
- throw new Error(`Block [${block.block}] is out of range`)
180
- }
181
- this._blockNumberIndex.set(block.block, block._hash)
182
- firstFound = block.block === this._firstNumber
183
- }
184
- } finally {
185
- this._blockNumberIndexSemaphore.release(BlockNumberIndexSemaphoreLocks)
186
- }
187
- }
188
- }