@rosen-bridge/abstract-scanner 0.1.0-52fc0239

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 (71) hide show
  1. package/README.md +49 -0
  2. package/dist/entities/blockEntity.d.ts +17 -0
  3. package/dist/entities/blockEntity.d.ts.map +1 -0
  4. package/dist/entities/blockEntity.js +78 -0
  5. package/dist/entities/extractorStatusEntity.d.ts +7 -0
  6. package/dist/entities/extractorStatusEntity.d.ts.map +1 -0
  7. package/dist/entities/extractorStatusEntity.js +37 -0
  8. package/dist/index.d.ts +11 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +10 -0
  11. package/dist/migrations/index.d.ts +7 -0
  12. package/dist/migrations/index.d.ts.map +1 -0
  13. package/dist/migrations/index.js +31 -0
  14. package/dist/migrations/postgres/1688545690867-migration.d.ts +7 -0
  15. package/dist/migrations/postgres/1688545690867-migration.d.ts.map +1 -0
  16. package/dist/migrations/postgres/1688545690867-migration.js +30 -0
  17. package/dist/migrations/postgres/1713803486477-migration.d.ts +7 -0
  18. package/dist/migrations/postgres/1713803486477-migration.d.ts.map +1 -0
  19. package/dist/migrations/postgres/1713803486477-migration.js +20 -0
  20. package/dist/migrations/postgres/1718789786123-migration.d.ts +7 -0
  21. package/dist/migrations/postgres/1718789786123-migration.d.ts.map +1 -0
  22. package/dist/migrations/postgres/1718789786123-migration.js +12 -0
  23. package/dist/migrations/postgres/1722697954558-migration.d.ts +7 -0
  24. package/dist/migrations/postgres/1722697954558-migration.d.ts.map +1 -0
  25. package/dist/migrations/postgres/1722697954558-migration.js +52 -0
  26. package/dist/migrations/postgres/1746701087567-migration.d.ts +7 -0
  27. package/dist/migrations/postgres/1746701087567-migration.d.ts.map +1 -0
  28. package/dist/migrations/postgres/1746701087567-migration.js +32 -0
  29. package/dist/migrations/postgres/1747657653564-migration.d.ts +7 -0
  30. package/dist/migrations/postgres/1747657653564-migration.d.ts.map +1 -0
  31. package/dist/migrations/postgres/1747657653564-migration.js +134 -0
  32. package/dist/migrations/sqlite/1688555497475-migration.d.ts +7 -0
  33. package/dist/migrations/sqlite/1688555497475-migration.d.ts.map +1 -0
  34. package/dist/migrations/sqlite/1688555497475-migration.js +29 -0
  35. package/dist/migrations/sqlite/1713786682123-migration.d.ts +7 -0
  36. package/dist/migrations/sqlite/1713786682123-migration.d.ts.map +1 -0
  37. package/dist/migrations/sqlite/1713786682123-migration.js +20 -0
  38. package/dist/migrations/sqlite/1718789744123-migration.d.ts +7 -0
  39. package/dist/migrations/sqlite/1718789744123-migration.d.ts.map +1 -0
  40. package/dist/migrations/sqlite/1718789744123-migration.js +12 -0
  41. package/dist/migrations/sqlite/1722697111974-migration.d.ts +7 -0
  42. package/dist/migrations/sqlite/1722697111974-migration.d.ts.map +1 -0
  43. package/dist/migrations/sqlite/1722697111974-migration.js +112 -0
  44. package/dist/migrations/sqlite/1746701087234-migration.d.ts +7 -0
  45. package/dist/migrations/sqlite/1746701087234-migration.d.ts.map +1 -0
  46. package/dist/migrations/sqlite/1746701087234-migration.js +32 -0
  47. package/dist/migrations/sqlite/1747655941239-migration.d.ts +7 -0
  48. package/dist/migrations/sqlite/1747655941239-migration.d.ts.map +1 -0
  49. package/dist/migrations/sqlite/1747655941239-migration.js +134 -0
  50. package/dist/scanner/abstract/generalScanner.d.ts +63 -0
  51. package/dist/scanner/abstract/generalScanner.d.ts.map +1 -0
  52. package/dist/scanner/abstract/generalScanner.js +173 -0
  53. package/dist/scanner/abstract/scanner.d.ts +48 -0
  54. package/dist/scanner/abstract/scanner.d.ts.map +1 -0
  55. package/dist/scanner/abstract/scanner.js +154 -0
  56. package/dist/scanner/abstract/webSocketScanner.d.ts +29 -0
  57. package/dist/scanner/abstract/webSocketScanner.d.ts.map +1 -0
  58. package/dist/scanner/abstract/webSocketScanner.js +89 -0
  59. package/dist/scanner/action.d.ts +83 -0
  60. package/dist/scanner/action.d.ts.map +1 -0
  61. package/dist/scanner/action.js +251 -0
  62. package/dist/scanner/interfaces.d.ts +12 -0
  63. package/dist/scanner/interfaces.d.ts.map +1 -0
  64. package/dist/scanner/interfaces.js +2 -0
  65. package/dist/scanner/network/ConnectorSelectionStrategies.d.ts +27 -0
  66. package/dist/scanner/network/ConnectorSelectionStrategies.d.ts.map +1 -0
  67. package/dist/scanner/network/ConnectorSelectionStrategies.js +22 -0
  68. package/dist/scanner/network/NetworkConnectorManager.d.ts +64 -0
  69. package/dist/scanner/network/NetworkConnectorManager.d.ts.map +1 -0
  70. package/dist/scanner/network/NetworkConnectorManager.js +125 -0
  71. package/package.json +54 -0
@@ -0,0 +1,83 @@
1
+ import { BlockEntity } from '../entities/blockEntity';
2
+ import { DataSource, DeleteResult, Repository } from '@rosen-bridge/extended-typeorm';
3
+ import { Block } from '@rosen-bridge/scanner-interfaces';
4
+ import { AbstractLogger } from '@rosen-bridge/abstract-logger';
5
+ import { ExtractorStatusEntity } from '../entities/extractorStatusEntity';
6
+ export declare class BlockDbAction {
7
+ readonly blockRepository: Repository<BlockEntity>;
8
+ readonly extractorStatusRepository: Repository<ExtractorStatusEntity>;
9
+ readonly dataSource: DataSource;
10
+ readonly scannerName: string;
11
+ readonly logger: AbstractLogger;
12
+ constructor(dataSource: DataSource, scannerName: string, logger?: AbstractLogger);
13
+ readonly name: () => string;
14
+ /**
15
+ * get last saved block
16
+ * @return Promise<BlockEntity or undefined>
17
+ */
18
+ getLastSavedBlock: () => Promise<BlockEntity | undefined>;
19
+ /**
20
+ * get last n stored blocks in database
21
+ * @param skip
22
+ * @param count
23
+ */
24
+ getLastSavedBlocks: (skip: number, count: number) => Promise<Array<BlockEntity>>;
25
+ /**
26
+ * get first saved block
27
+ * @return Promise<BlockEntity or undefined>
28
+ */
29
+ getFirstSavedBlock: () => Promise<BlockEntity | undefined>;
30
+ /**
31
+ * get block hash and height
32
+ * @param height
33
+ * @param status
34
+ * @return Promise<BlockEntity|undefined>
35
+ */
36
+ getBlockAtHeight: (height: number, status?: string) => Promise<BlockEntity | undefined>;
37
+ /**
38
+ * get block with entered blockhash
39
+ * @param hash
40
+ * @param status
41
+ */
42
+ getBlockWithHash: (hash: string, status?: string) => Promise<BlockEntity | null>;
43
+ /**
44
+ * it deletes every block that more than or equal height
45
+ * @param height
46
+ * @return Promise<DeleteResult>
47
+ */
48
+ removeBlocksFromHeight: (height: number) => Promise<DeleteResult>;
49
+ /**
50
+ * store a block into database.
51
+ * @param block
52
+ */
53
+ saveBlock: (block: Block) => Promise<BlockEntity | boolean>;
54
+ /**
55
+ * Update status of a block to proceed
56
+ * @param height: height of expected block
57
+ */
58
+ updateBlockStatus: (height: number, blockHash: string, extractorIds: string[]) => Promise<boolean>;
59
+ /**
60
+ * Update status of a block to processing in case of fork
61
+ * @param height: height of expected block
62
+ */
63
+ revertBlockStatus: (height: number, parentHash: string, extractorIds: string[]) => Promise<boolean>;
64
+ /**
65
+ * Insert a newly initialized extractor or update an existing extractor status
66
+ * @param extractorId
67
+ * @param height
68
+ * @returns
69
+ */
70
+ updateOrInsertExtractorStatus: (extractorId: string, height: number, blockHash: string) => Promise<{
71
+ scannerId: string;
72
+ extractorId: string;
73
+ updateHeight: number;
74
+ updateBlockHash: string;
75
+ } & ExtractorStatusEntity>;
76
+ /**
77
+ * Return extractors` status specified by id
78
+ * @param extractorIds
79
+ * @returns extractors` status
80
+ */
81
+ getExtractorsStatus: (extractorIds: string[]) => Promise<ExtractorStatusEntity[]>;
82
+ }
83
+ //# sourceMappingURL=action.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../../lib/scanner/action.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAuB,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EACL,UAAU,EACV,YAAY,EAEZ,UAAU,EAEX,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,kCAAkC,CAAC;AACzD,OAAO,EAAE,cAAc,EAAe,MAAM,+BAA+B,CAAC;AAC5E,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAE1E,qBAAa,aAAa;IACxB,QAAQ,CAAC,eAAe,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IAClD,QAAQ,CAAC,yBAAyB,EAAE,UAAU,CAAC,qBAAqB,CAAC,CAAC;IACtE,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;gBAG9B,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,cAAc;IAWzB,QAAQ,CAAC,IAAI,eAA0B;IAEvC;;;OAGG;IACH,iBAAiB,QAAa,QAAQ,WAAW,GAAG,SAAS,CAAC,CAW5D;IAEF;;;;OAIG;IACH,kBAAkB,SACV,MAAM,SACL,MAAM,KACZ,QAAQ,MAAM,WAAW,CAAC,CAAC,CAO5B;IAEF;;;OAGG;IACH,kBAAkB,QAAa,QAAQ,WAAW,GAAG,SAAS,CAAC,CAW7D;IAEF;;;;;OAKG;IACH,gBAAgB,WACN,MAAM,WACN,MAAM,KACb,QAAQ,WAAW,GAAG,SAAS,CAAC,CAWjC;IAEF;;;;OAIG;IACH,gBAAgB,SAAgB,MAAM,WAAU,MAAM,iCAMpD;IAEF;;;;OAIG;IACH,sBAAsB,WAAkB,MAAM,KAAG,QAAQ,YAAY,CAAC,CAMpE;IAEF;;;OAGG;IACH,SAAS,UAAiB,KAAK,KAAG,QAAQ,WAAW,GAAG,OAAO,CAAC,CA0C9D;IAEF;;;OAGG;IACH,iBAAiB,WACP,MAAM,aACH,MAAM,gBACH,MAAM,EAAE,KACrB,QAAQ,OAAO,CAAC,CAqCjB;IAEF;;;OAGG;IACH,iBAAiB,WACP,MAAM,cACF,MAAM,gBACJ,MAAM,EAAE,KACrB,QAAQ,OAAO,CAAC,CAsCjB;IAEF;;;;;OAKG;IACH,6BAA6B,gBACd,MAAM,UACX,MAAM,aACH,MAAM;;;;;+BAgBjB;IAEF;;;;OAIG;IACH,mBAAmB,iBACH,MAAM,EAAE,KACrB,QAAQ,qBAAqB,EAAE,CAAC,CAKjC;CACH"}
@@ -0,0 +1,251 @@
1
+ import { BlockEntity, PROCEED, PROCESSING } from '../entities/blockEntity';
2
+ import { MoreThanOrEqual, In, } from '@rosen-bridge/extended-typeorm';
3
+ import { DummyLogger } from '@rosen-bridge/abstract-logger';
4
+ import { ExtractorStatusEntity } from '../entities/extractorStatusEntity';
5
+ export class BlockDbAction {
6
+ blockRepository;
7
+ extractorStatusRepository;
8
+ dataSource;
9
+ scannerName;
10
+ logger;
11
+ constructor(dataSource, scannerName, logger) {
12
+ this.blockRepository = dataSource.getRepository(BlockEntity);
13
+ this.extractorStatusRepository = dataSource.getRepository(ExtractorStatusEntity);
14
+ this.dataSource = dataSource;
15
+ this.scannerName = scannerName;
16
+ this.logger = logger ? logger : new DummyLogger();
17
+ }
18
+ name = () => this.scannerName;
19
+ /**
20
+ * get last saved block
21
+ * @return Promise<BlockEntity or undefined>
22
+ */
23
+ getLastSavedBlock = async () => {
24
+ const lastBlock = await this.blockRepository.find({
25
+ where: { status: PROCEED, scanner: this.name() },
26
+ order: { height: 'DESC' },
27
+ take: 1,
28
+ });
29
+ if (lastBlock.length !== 0) {
30
+ return lastBlock[0];
31
+ }
32
+ else {
33
+ return undefined;
34
+ }
35
+ };
36
+ /**
37
+ * get last n stored blocks in database
38
+ * @param skip
39
+ * @param count
40
+ */
41
+ getLastSavedBlocks = async (skip, count) => {
42
+ return await this.blockRepository.find({
43
+ where: { status: PROCEED, scanner: this.name() },
44
+ order: { height: 'DESC' },
45
+ skip: skip,
46
+ take: count,
47
+ });
48
+ };
49
+ /**
50
+ * get first saved block
51
+ * @return Promise<BlockEntity or undefined>
52
+ */
53
+ getFirstSavedBlock = async () => {
54
+ const lastBlock = await this.blockRepository.find({
55
+ where: { status: PROCEED, scanner: this.name() },
56
+ order: { height: 'ASC' },
57
+ take: 1,
58
+ });
59
+ if (lastBlock.length !== 0) {
60
+ return lastBlock[0];
61
+ }
62
+ else {
63
+ return undefined;
64
+ }
65
+ };
66
+ /**
67
+ * get block hash and height
68
+ * @param height
69
+ * @param status
70
+ * @return Promise<BlockEntity|undefined>
71
+ */
72
+ getBlockAtHeight = async (height, status = PROCEED) => {
73
+ const block = await this.blockRepository.findOneBy({
74
+ status: status,
75
+ height: height,
76
+ scanner: this.name(),
77
+ });
78
+ if (block !== null) {
79
+ return block;
80
+ }
81
+ else {
82
+ return undefined;
83
+ }
84
+ };
85
+ /**
86
+ * get block with entered blockhash
87
+ * @param hash
88
+ * @param status
89
+ */
90
+ getBlockWithHash = async (hash, status = PROCEED) => {
91
+ return this.blockRepository.findOneBy({
92
+ hash: hash,
93
+ status: status,
94
+ scanner: this.name(),
95
+ });
96
+ };
97
+ /**
98
+ * it deletes every block that more than or equal height
99
+ * @param height
100
+ * @return Promise<DeleteResult>
101
+ */
102
+ removeBlocksFromHeight = async (height) => {
103
+ this.logger.debug(`Removing blocks from height ${height}`);
104
+ return await this.blockRepository.delete({
105
+ height: MoreThanOrEqual(height),
106
+ scanner: this.name(),
107
+ });
108
+ };
109
+ /**
110
+ * store a block into database.
111
+ * @param block
112
+ */
113
+ saveBlock = async (block) => {
114
+ try {
115
+ const instance = await this.blockRepository.findOneBy({
116
+ height: block.height,
117
+ scanner: this.name(),
118
+ });
119
+ const date = new Date(block.timestamp * 1000);
120
+ const blockInfo = {
121
+ height: block.height,
122
+ hash: block.hash,
123
+ parentHash: block.parentHash,
124
+ status: PROCESSING,
125
+ scanner: this.name(),
126
+ extra: block.extra,
127
+ timestamp: block.timestamp,
128
+ year: date.getFullYear(),
129
+ month: date.getMonth() + 1,
130
+ day: date.getDate(),
131
+ };
132
+ if (!instance) {
133
+ this.logger.debug(`Inserting block with info: ${JSON.stringify(blockInfo)}`);
134
+ await this.blockRepository.insert(blockInfo);
135
+ }
136
+ else {
137
+ this.logger.debug(`Updating block with info: ${JSON.stringify(blockInfo)}`);
138
+ await this.blockRepository.update({ height: block.height, scanner: this.name() }, blockInfo);
139
+ }
140
+ const res = await this.blockRepository.findOneBy({
141
+ height: block.height,
142
+ scanner: this.name(),
143
+ });
144
+ return res ? res : false;
145
+ }
146
+ catch (exp) {
147
+ this.logger.error(`An error occurred during save new block: ${exp}`);
148
+ return false;
149
+ }
150
+ };
151
+ /**
152
+ * Update status of a block to proceed
153
+ * @param height: height of expected block
154
+ */
155
+ updateBlockStatus = async (height, blockHash, extractorIds) => {
156
+ let success = true;
157
+ this.logger.debug(`Block at height ${height} has been proceed in scanner ${this.name()}, updating status`);
158
+ const runner = this.dataSource.createQueryRunner();
159
+ await runner.connect();
160
+ await runner.startTransaction();
161
+ try {
162
+ await runner.manager.getRepository(BlockEntity).update({
163
+ height: height,
164
+ status: PROCESSING,
165
+ scanner: this.name(),
166
+ }, {
167
+ status: PROCEED,
168
+ });
169
+ this.logger.debug('Updating extractors status', {
170
+ extractorIds,
171
+ });
172
+ await runner.manager
173
+ .getRepository(ExtractorStatusEntity)
174
+ .update({ extractorId: In(extractorIds), scannerId: this.name() }, { updateHeight: height, updateBlockHash: blockHash });
175
+ await runner.commitTransaction();
176
+ }
177
+ catch (e) {
178
+ await runner.rollbackTransaction();
179
+ success = false;
180
+ }
181
+ finally {
182
+ await runner.release();
183
+ }
184
+ return success;
185
+ };
186
+ /**
187
+ * Update status of a block to processing in case of fork
188
+ * @param height: height of expected block
189
+ */
190
+ revertBlockStatus = async (height, parentHash, extractorIds) => {
191
+ let success = true;
192
+ const runner = this.dataSource.createQueryRunner();
193
+ await runner.connect();
194
+ await runner.startTransaction();
195
+ try {
196
+ this.logger.debug(`Reverting block status at height ${height}`);
197
+ await runner.manager.getRepository(BlockEntity).update({
198
+ height: height,
199
+ status: PROCEED,
200
+ scanner: this.name(),
201
+ }, {
202
+ status: PROCESSING,
203
+ });
204
+ this.logger.debug(`Reverting extractors update height to previous block at height ${height - 1}`);
205
+ await runner.manager
206
+ .getRepository(ExtractorStatusEntity)
207
+ .update({ extractorId: In(extractorIds), scannerId: this.name() }, { updateHeight: height - 1, updateBlockHash: parentHash });
208
+ await runner.commitTransaction();
209
+ }
210
+ catch (e) {
211
+ this.logger.warn(`An Error occurred while reverting block status: ${e}`);
212
+ await runner.rollbackTransaction();
213
+ success = false;
214
+ }
215
+ finally {
216
+ await runner.release();
217
+ }
218
+ return success;
219
+ };
220
+ /**
221
+ * Insert a newly initialized extractor or update an existing extractor status
222
+ * @param extractorId
223
+ * @param height
224
+ * @returns
225
+ */
226
+ updateOrInsertExtractorStatus = async (extractorId, height, blockHash) => {
227
+ this.logger.debug('Inserting new extractor status or Updating existing resynced extractor status', {
228
+ extractorId,
229
+ height,
230
+ blockHash,
231
+ });
232
+ return await this.extractorStatusRepository.save({
233
+ scannerId: this.name(),
234
+ extractorId,
235
+ updateHeight: height,
236
+ updateBlockHash: blockHash,
237
+ });
238
+ };
239
+ /**
240
+ * Return extractors` status specified by id
241
+ * @param extractorIds
242
+ * @returns extractors` status
243
+ */
244
+ getExtractorsStatus = async (extractorIds) => {
245
+ return await this.extractorStatusRepository.findBy({
246
+ scannerId: this.name(),
247
+ extractorId: In(extractorIds),
248
+ });
249
+ };
250
+ }
251
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vbGliL3NjYW5uZXIvYWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzNFLE9BQU8sRUFHTCxlQUFlLEVBRWYsRUFBRSxHQUNILE1BQU0sZ0NBQWdDLENBQUM7QUFFeEMsT0FBTyxFQUFrQixXQUFXLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUM1RSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUUxRSxNQUFNLE9BQU8sYUFBYTtJQUNmLGVBQWUsQ0FBMEI7SUFDekMseUJBQXlCLENBQW9DO0lBQzdELFVBQVUsQ0FBYTtJQUN2QixXQUFXLENBQVM7SUFDcEIsTUFBTSxDQUFpQjtJQUVoQyxZQUNFLFVBQXNCLEVBQ3RCLFdBQW1CLEVBQ25CLE1BQXVCO1FBRXZCLElBQUksQ0FBQyxlQUFlLEdBQUcsVUFBVSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUM3RCxJQUFJLENBQUMseUJBQXlCLEdBQUcsVUFBVSxDQUFDLGFBQWEsQ0FDdkQscUJBQXFCLENBQ3RCLENBQUM7UUFDRixJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztRQUM3QixJQUFJLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztRQUMvQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLFdBQVcsRUFBRSxDQUFDO0lBQ3BELENBQUM7SUFFUSxJQUFJLEdBQUcsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQztJQUV2Qzs7O09BR0c7SUFDSCxpQkFBaUIsR0FBRyxLQUFLLElBQXNDLEVBQUU7UUFDL0QsTUFBTSxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFD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RUFDL0U7WUFDRSxXQUFXO1lBQ1gsTUFBTTtZQUNOLFNBQVM7U0FDVixDQUNGLENBQUM7UUFDRixPQUFPLE1BQU0sSUFBSSxDQUFDLHlCQUF5QixDQUFDLElBQUksQ0FBQztZQUMvQyxTQUFTLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRTtZQUN0QixXQUFXO1lBQ1gsWUFBWSxFQUFFLE1BQU07WUFDcEIsZUFBZSxFQUFFLFNBQVM7U0FDM0IsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDO0lBRUY7Ozs7T0FJRztJQUNILG1CQUFtQixHQUFHLEtBQUssRUFDekIsWUFBc0IsRUFDWSxFQUFFO1FBQ3BDLE9BQU8sTUFBTSxJQUFJLENBQUMseUJBQXlCLENBQUMsTUFBTSxDQUFDO1lBQ2pELFNBQVMsRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFO1lBQ3RCLFdBQVcsRUFBRSxFQUFFLENBQUMsWUFBWSxDQUFDO1NBQzlCLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQztDQUNIIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQmxvY2tFbnRpdHksIFBST0NFRUQsIFBST0NFU1NJTkcgfSBmcm9tICcuLi9lbnRpdGllcy9ibG9ja0VudGl0eSc7XG5pbXBvcnQge1xuICBEYXRhU291cmNlLFxuICBEZWxldGVSZXN1bHQsXG4gIE1vcmVUaGFuT3JFcXVhbCxcbiAgUmVwb3NpdG9yeSxcbiAgSW4sXG59IGZyb20gJ0Byb3Nlbi1icmlkZ2UvZXh0ZW5kZWQtdHlwZW9ybSc7XG5pbXBvcnQgeyBCbG9jayB9IGZyb20gJ0Byb3Nlbi1icmlkZ2Uvc2Nhbm5lci1pbnRlcmZhY2VzJztcbmltcG9ydCB7IEFic3RyYWN0TG9nZ2VyLCBEdW1teUxvZ2dlciB9IGZyb20gJ0Byb3Nlbi1icmlkZ2UvYWJzdHJhY3QtbG9nZ2VyJztcbmltcG9ydCB7IEV4dHJhY3RvclN0YXR1c0VudGl0eSB9IGZyb20gJy4uL2VudGl0aWVzL2V4dHJhY3RvclN0YXR1c0VudGl0eSc7XG5cbmV4cG9ydCBjbGFzcyBCbG9ja0RiQWN0aW9uIHtcbiAgcmVhZG9ubHkgYmxvY2tSZXBvc2l0b3J5OiBSZXBvc2l0b3J5PEJsb2NrRW50aXR5PjtcbiAgcmVhZG9ubHkgZXh0cmFjdG9yU3RhdHVzUmVwb3NpdG9yeTogUmVwb3NpdG9yeTxFeHRyYWN0b3JTdGF0dXNFbnRpdHk+O1xuICByZWFkb25seSBkYXRhU291cmNlOiBEYXRhU291cmNlO1xuICByZWFkb25seSBzY2FubmVyTmFtZTogc3RyaW5nO1xuICByZWFkb25seSBsb2dnZXI6IEFic3RyYWN0TG9nZ2VyO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGRhdGFTb3VyY2U6IERhdGFTb3VyY2UsXG4gICAgc2Nhbm5lck5hbWU6IHN0cmluZyxcbiAgICBsb2dnZXI/OiBBYnN0cmFjdExvZ2dlclxuICApIHtcbiAgICB0aGlzLmJsb2NrUmVwb3NpdG9yeSA9IGRhdGFTb3VyY2UuZ2V0UmVwb3NpdG9yeShCbG9ja0VudGl0eSk7XG4gICAgdGhpcy5leHRyYWN0b3JTdGF0dXNSZXBvc2l0b3J5ID0gZGF0YVNvdXJjZS5nZXRSZXBvc2l0b3J5KFxuICAgICAgRXh0cmFjdG9yU3RhdHVzRW50aXR5XG4gICAgKTtcbiAgICB0aGlzLmRhdGFTb3VyY2UgPSBkYXRhU291cmNlO1xuICAgIHRoaXMuc2Nhbm5lck5hbWUgPSBzY2FubmVyTmFtZTtcbiAgICB0aGlzLmxvZ2dlciA9IGxvZ2dlciA/IGxvZ2dlciA6IG5ldyBEdW1teUxvZ2dlcigpO1xuICB9XG5cbiAgcmVhZG9ubHkgbmFtZSA9ICgpID0+IHRoaXMuc2Nhbm5lck5hbWU7XG5cbiAgLyoqXG4gICAqIGdldCBsYXN0IHNhdmVkIGJsb2NrXG4gICAqIEByZXR1cm4gUHJvbWlzZTxCbG9ja0VudGl0eSBvciB1bmRlZmluZWQ+XG4gICAqL1xuICBnZXRMYXN0U2F2ZWRCbG9jayA9IGFzeW5jICgpOiBQcm9taXNlPEJsb2NrRW50aXR5IHwgdW5kZWZpbmVkPiA9PiB7XG4gICAgY29uc3QgbGFzdEJsb2NrID0gYXdhaXQgdGhpcy5ibG9ja1JlcG9zaXRvcnkuZmluZCh7XG4gICAgICB3aGVyZTogeyBzdGF0dXM6IFBST0NFRUQsIHNjYW5uZXI6IHRoaXMubmFtZSgpIH0sXG4gICAgICBvcmRlcjogeyBoZWlnaHQ6ICdERVNDJyB9LFxuICAgICAgdGFrZTogMSxcbiAgICB9KTtcbiAgICBpZiAobGFzdEJsb2NrLmxlbmd0aCAhPT0gMCkge1xuICAgICAgcmV0dXJuIGxhc3RCbG9ja1swXTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIGdldCBsYXN0IG4gc3RvcmVkIGJsb2NrcyBpbiBkYXRhYmFzZVxuICAgKiBAcGFyYW0gc2tpcFxuICAgKiBAcGFyYW0gY291bnRcbiAgICovXG4gIGdldExhc3RTYXZlZEJsb2NrcyA9IGFzeW5jIChcbiAgICBza2lwOiBudW1iZXIsXG4gICAgY291bnQ6IG51bWJlclxuICApOiBQcm9taXNlPEFycmF5PEJsb2NrRW50aXR5Pj4gPT4ge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLmJsb2NrUmVwb3NpdG9yeS5maW5kKHtcbiAgICAgIHdoZXJlOiB7IHN0YXR1czogUFJPQ0VFRCwgc2Nhbm5lcjogdGhpcy5uYW1lKCkgfSxcbiAgICAgIG9yZGVyOiB7IGhlaWdodDogJ0RFU0MnIH0sXG4gICAgICBza2lwOiBza2lwLFxuICAgICAgdGFrZTogY291bnQsXG4gICAgfSk7XG4gIH07XG5cbiAgLyoqXG4gICAqIGdldCBmaXJzdCBzYXZlZCBibG9ja1xuICAgKiBAcmV0dXJuIFByb21pc2U8QmxvY2tFbnRpdHkgb3IgdW5kZWZpbmVkPlxuICAgKi9cbiAgZ2V0Rmlyc3RTYXZlZEJsb2NrID0gYXN5bmMgKCk6IFByb21pc2U8QmxvY2tFbnRpdHkgfCB1bmRlZmluZWQ+ID0+IHtcbiAgICBjb25zdCBsYXN0QmxvY2sgPSBhd2FpdCB0aGlzLmJsb2NrUmVwb3NpdG9yeS5maW5kKHtcbiAgICAgIHdoZXJlOiB7IHN0YXR1czogUFJPQ0VFRCwgc2Nhbm5lcjogdGhpcy5uYW1lKCkgfSxcbiAgICAgIG9yZGVyOiB7IGhlaWdodDogJ0FTQycgfSxcbiAgICAgIHRha2U6IDEsXG4gICAgfSk7XG4gICAgaWYgKGxhc3RCbG9jay5sZW5ndGggIT09IDApIHtcbiAgICAgIHJldHVybiBsYXN0QmxvY2tbMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBnZXQgYmxvY2sgaGFzaCBhbmQgaGVpZ2h0XG4gICAqIEBwYXJhbSBoZWlnaHRcbiAgICogQHBhcmFtIHN0YXR1c1xuICAgKiBAcmV0dXJuIFByb21pc2U8QmxvY2tFbnRpdHl8dW5kZWZpbmVkPlxuICAgKi9cbiAgZ2V0QmxvY2tBdEhlaWdodCA9IGFzeW5jIChcbiAgICBoZWlnaHQ6IG51bWJlcixcbiAgICBzdGF0dXM6IHN0cmluZyA9IFBST0NFRURcbiAgKTogUHJvbWlzZTxCbG9ja0VudGl0eSB8IHVuZGVmaW5lZD4gPT4ge1xuICAgIGNvbnN0IGJsb2NrID0gYXdhaXQgdGhpcy5ibG9ja1JlcG9zaXRvcnkuZmluZE9uZUJ5KHtcbiAgICAgIHN0YXR1czogc3RhdHVzLFxuICAgICAgaGVpZ2h0OiBoZWlnaHQsXG4gICAgICBzY2FubmVyOiB0aGlzLm5hbWUoKSxcbiAgICB9KTtcbiAgICBpZiAoYmxvY2sgIT09IG51bGwpIHtcbiAgICAgIHJldHVybiBibG9jaztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIGdldCBibG9jayB3aXRoIGVudGVyZWQgYmxvY2toYXNoXG4gICAqIEBwYXJhbSBoYXNoXG4gICAqIEBwYXJhbSBzdGF0dXNcbiAgICovXG4gIGdldEJsb2NrV2l0aEhhc2ggPSBhc3luYyAoaGFzaDogc3RyaW5nLCBzdGF0dXM6IHN0cmluZyA9IFBST0NFRUQpID0+IHtcbiAgICByZXR1cm4gdGhpcy5ibG9ja1JlcG9zaXRvcnkuZmluZE9uZUJ5KHtcbiAgICAgIGhhc2g6IGhhc2gsXG4gICAgICBzdGF0dXM6IHN0YXR1cyxcbiAgICAgIHNjYW5uZXI6IHRoaXMubmFtZSgpLFxuICAgIH0pO1xuICB9O1xuXG4gIC8qKlxuICAgKiBpdCBkZWxldGVzIGV2ZXJ5IGJsb2NrIHRoYXQgbW9yZSB0aGFuIG9yIGVxdWFsIGhlaWdodFxuICAgKiBAcGFyYW0gaGVpZ2h0XG4gICAqIEByZXR1cm4gUHJvbWlzZTxEZWxldGVSZXN1bHQ+XG4gICAqL1xuICByZW1vdmVCbG9ja3NGcm9tSGVpZ2h0ID0gYXN5bmMgKGhlaWdodDogbnVtYmVyKTogUHJvbWlzZTxEZWxldGVSZXN1bHQ+ID0+IHtcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgUmVtb3ZpbmcgYmxvY2tzIGZyb20gaGVpZ2h0ICR7aGVpZ2h0fWApO1xuICAgIHJldHVybiBhd2FpdCB0aGlzLmJsb2NrUmVwb3NpdG9yeS5kZWxldGUoe1xuICAgICAgaGVpZ2h0OiBNb3JlVGhhbk9yRXF1YWwoaGVpZ2h0KSxcbiAgICAgIHNjYW5uZXI6IHRoaXMubmFtZSgpLFxuICAgIH0pO1xuICB9O1xuXG4gIC8qKlxuICAgKiBzdG9yZSBhIGJsb2NrIGludG8gZGF0YWJhc2UuXG4gICAqIEBwYXJhbSBibG9ja1xuICAgKi9cbiAgc2F2ZUJsb2NrID0gYXN5bmMgKGJsb2NrOiBCbG9jayk6IFByb21pc2U8QmxvY2tFbnRpdHkgfCBib29sZWFuPiA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGluc3RhbmNlID0gYXdhaXQgdGhpcy5ibG9ja1JlcG9zaXRvcnkuZmluZE9uZUJ5KHtcbiAgICAgICAgaGVpZ2h0OiBibG9jay5oZWlnaHQsXG4gICAgICAgIHNjYW5uZXI6IHRoaXMubmFtZSgpLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoYmxvY2sudGltZXN0YW1wICogMTAwMCk7XG4gICAgICBjb25zdCBibG9ja0luZm8gPSB7XG4gICAgICAgIGhlaWdodDogYmxvY2suaGVpZ2h0LFxuICAgICAgICBoYXNoOiBibG9jay5oYXNoLFxuICAgICAgICBwYXJlbnRIYXNoOiBibG9jay5wYXJlbnRIYXNoLFxuICAgICAgICBzdGF0dXM6IFBST0NFU1NJTkcsXG4gICAgICAgIHNjYW5uZXI6IHRoaXMubmFtZSgpLFxuICAgICAgICBleHRyYTogYmxvY2suZXh0cmEsXG4gICAgICAgIHRpbWVzdGFtcDogYmxvY2sudGltZXN0YW1wLFxuICAgICAgICB5ZWFyOiBkYXRlLmdldEZ1bGxZZWFyKCksXG4gICAgICAgIG1vbnRoOiBkYXRlLmdldE1vbnRoKCkgKyAxLFxuICAgICAgICBkYXk6IGRhdGUuZ2V0RGF0ZSgpLFxuICAgICAgfTtcbiAgICAgIGlmICghaW5zdGFuY2UpIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoXG4gICAgICAgICAgYEluc2VydGluZyBibG9jayB3aXRoIGluZm86ICR7SlNPTi5zdHJpbmdpZnkoYmxvY2tJbmZvKX1gXG4gICAgICAgICk7XG4gICAgICAgIGF3YWl0IHRoaXMuYmxvY2tSZXBvc2l0b3J5Lmluc2VydChibG9ja0luZm8pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoXG4gICAgICAgICAgYFVwZGF0aW5nIGJsb2NrIHdpdGggaW5mbzogJHtKU09OLnN0cmluZ2lmeShibG9ja0luZm8pfWBcbiAgICAgICAgKTtcbiAgICAgICAgYXdhaXQgdGhpcy5ibG9ja1JlcG9zaXRvcnkudXBkYXRlKFxuICAgICAgICAgIHsgaGVpZ2h0OiBibG9jay5oZWlnaHQsIHNjYW5uZXI6IHRoaXMubmFtZSgpIH0sXG4gICAgICAgICAgYmxvY2tJbmZvXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmJsb2NrUmVwb3NpdG9yeS5maW5kT25lQnkoe1xuICAgICAgICBoZWlnaHQ6IGJsb2NrLmhlaWdodCxcbiAgICAgICAgc2Nhbm5lcjogdGhpcy5uYW1lKCksXG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXMgPyByZXMgOiBmYWxzZTtcbiAgICB9IGNhdGNoIChleHApIHtcbiAgICAgIHRoaXMubG9nZ2VyLmVycm9yKGBBbiBlcnJvciBvY2N1cnJlZCBkdXJpbmcgc2F2ZSBuZXcgYmxvY2s6ICR7ZXhwfWApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogVXBkYXRlIHN0YXR1cyBvZiBhIGJsb2NrIHRvIHByb2NlZWRcbiAgICogQHBhcmFtIGhlaWdodDogaGVpZ2h0IG9mIGV4cGVjdGVkIGJsb2NrXG4gICAqL1xuICB1cGRhdGVCbG9ja1N0YXR1cyA9IGFzeW5jIChcbiAgICBoZWlnaHQ6IG51bWJlcixcbiAgICBibG9ja0hhc2g6IHN0cmluZyxcbiAgICBleHRyYWN0b3JJZHM6IHN0cmluZ1tdXG4gICk6IFByb21pc2U8Ym9vbGVhbj4gPT4ge1xuICAgIGxldCBzdWNjZXNzID0gdHJ1ZTtcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcbiAgICAgIGBCbG9jayBhdCBoZWlnaHQgJHtoZWlnaHR9IGhhcyBiZWVuIHByb2NlZWQgaW4gc2Nhbm5lciAke3RoaXMubmFtZSgpfSwgdXBkYXRpbmcgc3RhdHVzYFxuICAgICk7XG4gICAgY29uc3QgcnVubmVyID0gdGhpcy5kYXRhU291cmNlLmNyZWF0ZVF1ZXJ5UnVubmVyKCk7XG4gICAgYXdhaXQgcnVubmVyLmNvbm5lY3QoKTtcbiAgICBhd2FpdCBydW5uZXIuc3RhcnRUcmFuc2FjdGlvbigpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBydW5uZXIubWFuYWdlci5nZXRSZXBvc2l0b3J5KEJsb2NrRW50aXR5KS51cGRhdGUoXG4gICAgICAgIHtcbiAgICAgICAgICBoZWlnaHQ6IGhlaWdodCxcbiAgICAgICAgICBzdGF0dXM6IFBST0NFU1NJTkcsXG4gICAgICAgICAgc2Nhbm5lcjogdGhpcy5uYW1lKCksXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBzdGF0dXM6IFBST0NFRUQsXG4gICAgICAgIH1cbiAgICAgICk7XG5cbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKCdVcGRhdGluZyBleHRyYWN0b3JzIHN0YXR1cycsIHtcbiAgICAgICAgZXh0cmFjdG9ySWRzLFxuICAgICAgfSk7XG4gICAgICBhd2FpdCBydW5uZXIubWFuYWdlclxuICAgICAgICAuZ2V0UmVwb3NpdG9yeShFeHRyYWN0b3JTdGF0dXNFbnRpdHkpXG4gICAgICAgIC51cGRhdGUoXG4gICAgICAgICAgeyBleHRyYWN0b3JJZDogSW4oZXh0cmFjdG9ySWRzKSwgc2Nhbm5lcklkOiB0aGlzLm5hbWUoKSB9LFxuICAgICAgICAgIHsgdXBkYXRlSGVpZ2h0OiBoZWlnaHQsIHVwZGF0ZUJsb2NrSGFzaDogYmxvY2tIYXNoIH1cbiAgICAgICAgKTtcbiAgICAgIGF3YWl0IHJ1bm5lci5jb21taXRUcmFuc2FjdGlvbigpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGF3YWl0IHJ1bm5lci5yb2xsYmFja1RyYW5zYWN0aW9uKCk7XG4gICAgICBzdWNjZXNzID0gZmFsc2U7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IHJ1bm5lci5yZWxlYXNlKCk7XG4gICAgfVxuICAgIHJldHVybiBzdWNjZXNzO1xuICB9O1xuXG4gIC8qKlxuICAgKiBVcGRhdGUgc3RhdHVzIG9mIGEgYmxvY2sgdG8gcHJvY2Vzc2luZyBpbiBjYXNlIG9mIGZvcmtcbiAgICogQHBhcmFtIGhlaWdodDogaGVpZ2h0IG9mIGV4cGVjdGVkIGJsb2NrXG4gICAqL1xuICByZXZlcnRCbG9ja1N0YXR1cyA9IGFzeW5jIChcbiAgICBoZWlnaHQ6IG51bWJlcixcbiAgICBwYXJlbnRIYXNoOiBzdHJpbmcsXG4gICAgZXh0cmFjdG9ySWRzOiBzdHJpbmdbXVxuICApOiBQcm9taXNlPGJvb2xlYW4+ID0+IHtcbiAgICBsZXQgc3VjY2VzcyA9IHRydWU7XG4gICAgY29uc3QgcnVubmVyID0gdGhpcy5kYXRhU291cmNlLmNyZWF0ZVF1ZXJ5UnVubmVyKCk7XG4gICAgYXdhaXQgcnVubmVyLmNvbm5lY3QoKTtcbiAgICBhd2FpdCBydW5uZXIuc3RhcnRUcmFuc2FjdGlvbigpO1xuICAgIHRyeSB7XG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgUmV2ZXJ0aW5nIGJsb2NrIHN0YXR1cyBhdCBoZWlnaHQgJHtoZWlnaHR9YCk7XG4gICAgICBhd2FpdCBydW5uZXIubWFuYWdlci5nZXRSZXBvc2l0b3J5KEJsb2NrRW50aXR5KS51cGRhdGUoXG4gICAgICAgIHtcbiAgICAgICAgICBoZWlnaHQ6IGhlaWdodCxcbiAgICAgICAgICBzdGF0dXM6IFBST0NFRUQsXG4gICAgICAgICAgc2Nhbm5lcjogdGhpcy5uYW1lKCksXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBzdGF0dXM6IFBST0NFU1NJTkcsXG4gICAgICAgIH1cbiAgICAgICk7XG5cbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKFxuICAgICAgICBgUmV2ZXJ0aW5nIGV4dHJhY3RvcnMgdXBkYXRlIGhlaWdodCB0byBwcmV2aW91cyBibG9jayBhdCBoZWlnaHQgJHtcbiAgICAgICAgICBoZWlnaHQgLSAxXG4gICAgICAgIH1gXG4gICAgICApO1xuICAgICAgYXdhaXQgcnVubmVyLm1hbmFnZXJcbiAgICAgICAgLmdldFJlcG9zaXRvcnkoRXh0cmFjdG9yU3RhdHVzRW50aXR5KVxuICAgICAgICAudXBkYXRlKFxuICAgICAgICAgIHsgZXh0cmFjdG9ySWQ6IEluKGV4dHJhY3RvcklkcyksIHNjYW5uZXJJZDogdGhpcy5uYW1lKCkgfSxcbiAgICAgICAgICB7IHVwZGF0ZUhlaWdodDogaGVpZ2h0IC0gMSwgdXBkYXRlQmxvY2tIYXNoOiBwYXJlbnRIYXNoIH1cbiAgICAgICAgKTtcbiAgICAgIGF3YWl0IHJ1bm5lci5jb21taXRUcmFuc2FjdGlvbigpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMubG9nZ2VyLndhcm4oYEFuIEVycm9yIG9jY3VycmVkIHdoaWxlIHJldmVydGluZyBibG9jayBzdGF0dXM6ICR7ZX1gKTtcbiAgICAgIGF3YWl0IHJ1bm5lci5yb2xsYmFja1RyYW5zYWN0aW9uKCk7XG4gICAgICBzdWNjZXNzID0gZmFsc2U7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IHJ1bm5lci5yZWxlYXNlKCk7XG4gICAgfVxuICAgIHJldHVybiBzdWNjZXNzO1xuICB9O1xuXG4gIC8qKlxuICAgKiBJbnNlcnQgYSBuZXdseSBpbml0aWFsaXplZCBleHRyYWN0b3Igb3IgdXBkYXRlIGFuIGV4aXN0aW5nIGV4dHJhY3RvciBzdGF0dXNcbiAgICogQHBhcmFtIGV4dHJhY3RvcklkXG4gICAqIEBwYXJhbSBoZWlnaHRcbiAgICogQHJldHVybnNcbiAgICovXG4gIHVwZGF0ZU9ySW5zZXJ0RXh0cmFjdG9yU3RhdHVzID0gYXN5bmMgKFxuICAgIGV4dHJhY3RvcklkOiBzdHJpbmcsXG4gICAgaGVpZ2h0OiBudW1iZXIsXG4gICAgYmxvY2tIYXNoOiBzdHJpbmdcbiAgKSA9PiB7XG4gICAgdGhpcy5sb2dnZXIuZGVidWcoXG4gICAgICAnSW5zZXJ0aW5nIG5ldyBleHRyYWN0b3Igc3RhdHVzIG9yIFVwZGF0aW5nIGV4aXN0aW5nIHJlc3luY2VkIGV4dHJhY3RvciBzdGF0dXMnLFxuICAgICAge1xuICAgICAgICBleHRyYWN0b3JJZCxcbiAgICAgICAgaGVpZ2h0LFxuICAgICAgICBibG9ja0hhc2gsXG4gICAgICB9XG4gICAgKTtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5leHRyYWN0b3JTdGF0dXNSZXBvc2l0b3J5LnNhdmUoe1xuICAgICAgc2Nhbm5lcklkOiB0aGlzLm5hbWUoKSxcbiAgICAgIGV4dHJhY3RvcklkLFxuICAgICAgdXBkYXRlSGVpZ2h0OiBoZWlnaHQsXG4gICAgICB1cGRhdGVCbG9ja0hhc2g6IGJsb2NrSGFzaCxcbiAgICB9KTtcbiAgfTtcblxuICAvKipcbiAgICogUmV0dXJuIGV4dHJhY3RvcnNgIHN0YXR1cyBzcGVjaWZpZWQgYnkgaWRcbiAgICogQHBhcmFtIGV4dHJhY3Rvcklkc1xuICAgKiBAcmV0dXJucyBleHRyYWN0b3JzYCBzdGF0dXNcbiAgICovXG4gIGdldEV4dHJhY3RvcnNTdGF0dXMgPSBhc3luYyAoXG4gICAgZXh0cmFjdG9ySWRzOiBzdHJpbmdbXVxuICApOiBQcm9taXNlPEV4dHJhY3RvclN0YXR1c0VudGl0eVtdPiA9PiB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuZXh0cmFjdG9yU3RhdHVzUmVwb3NpdG9yeS5maW5kQnkoe1xuICAgICAgc2Nhbm5lcklkOiB0aGlzLm5hbWUoKSxcbiAgICAgIGV4dHJhY3RvcklkOiBJbihleHRyYWN0b3JJZHMpLFxuICAgIH0pO1xuICB9O1xufVxuIl19
@@ -0,0 +1,12 @@
1
+ import { AbstractLogger } from '@rosen-bridge/abstract-logger';
2
+ import { DataSource } from '@rosen-bridge/extended-typeorm';
3
+ import { AbstractNetworkConnector } from '@rosen-bridge/scanner-interfaces';
4
+ export interface ScannerConfig<TransactionType> {
5
+ dataSource: DataSource;
6
+ initialHeight: number;
7
+ network: AbstractNetworkConnector<TransactionType>;
8
+ blockRetrieveGap?: number;
9
+ suffix?: string;
10
+ logger?: AbstractLogger;
11
+ }
12
+ //# sourceMappingURL=interfaces.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../../lib/scanner/interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAE5E,MAAM,WAAW,aAAa,CAAC,eAAe;IAC5C,UAAU,EAAE,UAAU,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,wBAAwB,CAAC,eAAe,CAAC,CAAC;IACnD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJmYWNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL2xpYi9zY2FubmVyL2ludGVyZmFjZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFic3RyYWN0TG9nZ2VyIH0gZnJvbSAnQHJvc2VuLWJyaWRnZS9hYnN0cmFjdC1sb2dnZXInO1xuaW1wb3J0IHsgRGF0YVNvdXJjZSB9IGZyb20gJ0Byb3Nlbi1icmlkZ2UvZXh0ZW5kZWQtdHlwZW9ybSc7XG5pbXBvcnQgeyBBYnN0cmFjdE5ldHdvcmtDb25uZWN0b3IgfSBmcm9tICdAcm9zZW4tYnJpZGdlL3NjYW5uZXItaW50ZXJmYWNlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2Nhbm5lckNvbmZpZzxUcmFuc2FjdGlvblR5cGU+IHtcbiAgZGF0YVNvdXJjZTogRGF0YVNvdXJjZTtcbiAgaW5pdGlhbEhlaWdodDogbnVtYmVyO1xuICBuZXR3b3JrOiBBYnN0cmFjdE5ldHdvcmtDb25uZWN0b3I8VHJhbnNhY3Rpb25UeXBlPjtcbiAgYmxvY2tSZXRyaWV2ZUdhcD86IG51bWJlcjtcbiAgc3VmZml4Pzogc3RyaW5nO1xuICBsb2dnZXI/OiBBYnN0cmFjdExvZ2dlcjtcbn1cbiJdfQ==
@@ -0,0 +1,27 @@
1
+ import { AbstractNetworkConnector } from '@rosen-bridge/scanner-interfaces';
2
+ /**
3
+ * Interface for connector selection strategies
4
+ */
5
+ export interface ConnectorSelectionStrategy<TransactionType> {
6
+ /**
7
+ * Select the next connector to use
8
+ * @param connectors Array of available connectors
9
+ * @param currentIndex Current connector index
10
+ * @param lastError Error from the last operation, if any
11
+ * @returns The index of the next connector to use
12
+ */
13
+ selectNextConnector(connectors: Array<AbstractNetworkConnector<TransactionType>>, currentIndex: number, lastError?: Error): number;
14
+ }
15
+ /**
16
+ * Failover strategy - switches to next connector only on failure
17
+ */
18
+ export declare class FailoverStrategy<TransactionType> implements ConnectorSelectionStrategy<TransactionType> {
19
+ selectNextConnector(connectors: Array<AbstractNetworkConnector<TransactionType>>, currentIndex: number, lastError?: Error): number;
20
+ }
21
+ /**
22
+ * Round-robin strategy - switches to next connector after each operation
23
+ */
24
+ export declare class RoundRobinStrategy<TransactionType> implements ConnectorSelectionStrategy<TransactionType> {
25
+ selectNextConnector(connectors: Array<AbstractNetworkConnector<TransactionType>>, currentIndex: number): number;
26
+ }
27
+ //# sourceMappingURL=ConnectorSelectionStrategies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConnectorSelectionStrategies.d.ts","sourceRoot":"","sources":["../../../lib/scanner/network/ConnectorSelectionStrategies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAE5E;;GAEG;AACH,MAAM,WAAW,0BAA0B,CAAC,eAAe;IACzD;;;;;;OAMG;IACH,mBAAmB,CACjB,UAAU,EAAE,KAAK,CAAC,wBAAwB,CAAC,eAAe,CAAC,CAAC,EAC5D,YAAY,EAAE,MAAM,EACpB,SAAS,CAAC,EAAE,KAAK,GAChB,MAAM,CAAC;CACX;AAED;;GAEG;AACH,qBAAa,gBAAgB,CAAC,eAAe,CAC3C,YAAW,0BAA0B,CAAC,eAAe,CAAC;IAEtD,mBAAmB,CACjB,UAAU,EAAE,KAAK,CAAC,wBAAwB,CAAC,eAAe,CAAC,CAAC,EAC5D,YAAY,EAAE,MAAM,EACpB,SAAS,CAAC,EAAE,KAAK,GAChB,MAAM;CAQV;AAED;;GAEG;AACH,qBAAa,kBAAkB,CAAC,eAAe,CAC7C,YAAW,0BAA0B,CAAC,eAAe,CAAC;IAEtD,mBAAmB,CACjB,UAAU,EAAE,KAAK,CAAC,wBAAwB,CAAC,eAAe,CAAC,CAAC,EAC5D,YAAY,EAAE,MAAM,GACnB,MAAM;CAGV"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Failover strategy - switches to next connector only on failure
3
+ */
4
+ export class FailoverStrategy {
5
+ selectNextConnector(connectors, currentIndex, lastError) {
6
+ // If there was an error, try the next connector
7
+ if (lastError) {
8
+ return (currentIndex + 1) % connectors.length;
9
+ }
10
+ // Otherwise stay with current connector
11
+ return currentIndex;
12
+ }
13
+ }
14
+ /**
15
+ * Round-robin strategy - switches to next connector after each operation
16
+ */
17
+ export class RoundRobinStrategy {
18
+ selectNextConnector(connectors, currentIndex) {
19
+ return (currentIndex + 1) % connectors.length;
20
+ }
21
+ }
22
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29ubmVjdG9yU2VsZWN0aW9uU3RyYXRlZ2llcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9zY2FubmVyL25ldHdvcmsvQ29ubmVjdG9yU2VsZWN0aW9uU3RyYXRlZ2llcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFvQkE7O0dBRUc7QUFDSCxNQUFNLE9BQU8sZ0JBQWdCO0lBRzNCLG1CQUFtQixDQUNqQixVQUE0RCxFQUM1RCxZQUFvQixFQUNwQixTQUFpQjtRQUVqQixnREFBZ0Q7UUFDaEQsSUFBSSxTQUFTLEVBQUU7WUFDYixPQUFPLENBQUMsWUFBWSxHQUFHLENBQUMsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUM7U0FDL0M7UUFDRCx3Q0FBd0M7UUFDeEMsT0FBTyxZQUFZLENBQUM7SUFDdEIsQ0FBQztDQUNGO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLE9BQU8sa0JBQWtCO0lBRzdCLG1CQUFtQixDQUNqQixVQUE0RCxFQUM1RCxZQUFvQjtRQUVwQixPQUFPLENBQUMsWUFBWSxHQUFHLENBQUMsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUM7SUFDaEQsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWJzdHJhY3ROZXR3b3JrQ29ubmVjdG9yIH0gZnJvbSAnQHJvc2VuLWJyaWRnZS9zY2FubmVyLWludGVyZmFjZXMnO1xuXG4vKipcbiAqIEludGVyZmFjZSBmb3IgY29ubmVjdG9yIHNlbGVjdGlvbiBzdHJhdGVnaWVzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29ubmVjdG9yU2VsZWN0aW9uU3RyYXRlZ3k8VHJhbnNhY3Rpb25UeXBlPiB7XG4gIC8qKlxuICAgKiBTZWxlY3QgdGhlIG5leHQgY29ubmVjdG9yIHRvIHVzZVxuICAgKiBAcGFyYW0gY29ubmVjdG9ycyBBcnJheSBvZiBhdmFpbGFibGUgY29ubmVjdG9yc1xuICAgKiBAcGFyYW0gY3VycmVudEluZGV4IEN1cnJlbnQgY29ubmVjdG9yIGluZGV4XG4gICAqIEBwYXJhbSBsYXN0RXJyb3IgRXJyb3IgZnJvbSB0aGUgbGFzdCBvcGVyYXRpb24sIGlmIGFueVxuICAgKiBAcmV0dXJucyBUaGUgaW5kZXggb2YgdGhlIG5leHQgY29ubmVjdG9yIHRvIHVzZVxuICAgKi9cbiAgc2VsZWN0TmV4dENvbm5lY3RvcihcbiAgICBjb25uZWN0b3JzOiBBcnJheTxBYnN0cmFjdE5ldHdvcmtDb25uZWN0b3I8VHJhbnNhY3Rpb25UeXBlPj4sXG4gICAgY3VycmVudEluZGV4OiBudW1iZXIsXG4gICAgbGFzdEVycm9yPzogRXJyb3JcbiAgKTogbnVtYmVyO1xufVxuXG4vKipcbiAqIEZhaWxvdmVyIHN0cmF0ZWd5IC0gc3dpdGNoZXMgdG8gbmV4dCBjb25uZWN0b3Igb25seSBvbiBmYWlsdXJlXG4gKi9cbmV4cG9ydCBjbGFzcyBGYWlsb3ZlclN0cmF0ZWd5PFRyYW5zYWN0aW9uVHlwZT5cbiAgaW1wbGVtZW50cyBDb25uZWN0b3JTZWxlY3Rpb25TdHJhdGVneTxUcmFuc2FjdGlvblR5cGU+XG57XG4gIHNlbGVjdE5leHRDb25uZWN0b3IoXG4gICAgY29ubmVjdG9yczogQXJyYXk8QWJzdHJhY3ROZXR3b3JrQ29ubmVjdG9yPFRyYW5zYWN0aW9uVHlwZT4+LFxuICAgIGN1cnJlbnRJbmRleDogbnVtYmVyLFxuICAgIGxhc3RFcnJvcj86IEVycm9yXG4gICk6IG51bWJlciB7XG4gICAgLy8gSWYgdGhlcmUgd2FzIGFuIGVycm9yLCB0cnkgdGhlIG5leHQgY29ubmVjdG9yXG4gICAgaWYgKGxhc3RFcnJvcikge1xuICAgICAgcmV0dXJuIChjdXJyZW50SW5kZXggKyAxKSAlIGNvbm5lY3RvcnMubGVuZ3RoO1xuICAgIH1cbiAgICAvLyBPdGhlcndpc2Ugc3RheSB3aXRoIGN1cnJlbnQgY29ubmVjdG9yXG4gICAgcmV0dXJuIGN1cnJlbnRJbmRleDtcbiAgfVxufVxuXG4vKipcbiAqIFJvdW5kLXJvYmluIHN0cmF0ZWd5IC0gc3dpdGNoZXMgdG8gbmV4dCBjb25uZWN0b3IgYWZ0ZXIgZWFjaCBvcGVyYXRpb25cbiAqL1xuZXhwb3J0IGNsYXNzIFJvdW5kUm9iaW5TdHJhdGVneTxUcmFuc2FjdGlvblR5cGU+XG4gIGltcGxlbWVudHMgQ29ubmVjdG9yU2VsZWN0aW9uU3RyYXRlZ3k8VHJhbnNhY3Rpb25UeXBlPlxue1xuICBzZWxlY3ROZXh0Q29ubmVjdG9yKFxuICAgIGNvbm5lY3RvcnM6IEFycmF5PEFic3RyYWN0TmV0d29ya0Nvbm5lY3RvcjxUcmFuc2FjdGlvblR5cGU+PixcbiAgICBjdXJyZW50SW5kZXg6IG51bWJlclxuICApOiBudW1iZXIge1xuICAgIHJldHVybiAoY3VycmVudEluZGV4ICsgMSkgJSBjb25uZWN0b3JzLmxlbmd0aDtcbiAgfVxufVxuIl19
@@ -0,0 +1,64 @@
1
+ import { AbstractNetworkConnector, Block } from '@rosen-bridge/scanner-interfaces';
2
+ import { ConnectorSelectionStrategy } from './ConnectorSelectionStrategies';
3
+ import { AbstractLogger } from '@rosen-bridge/abstract-logger';
4
+ /**
5
+ * Network connector manager that can handle multiple connectors
6
+ * for a single network with pluggable selection strategy
7
+ */
8
+ export declare class NetworkConnectorManager<TransactionType> implements AbstractNetworkConnector<TransactionType> {
9
+ private strategy;
10
+ private logger;
11
+ private connectors;
12
+ private currentConnectorIndex;
13
+ constructor(strategy?: ConnectorSelectionStrategy<TransactionType>, logger?: AbstractLogger);
14
+ /**
15
+ * Add a new connector to the manager
16
+ * @param connector The network connector instance
17
+ */
18
+ addConnector(connector: AbstractNetworkConnector<TransactionType>): void;
19
+ /**
20
+ * Get the current active connector
21
+ * @returns The current network connector instance
22
+ * @throws Error if no connectors are available
23
+ */
24
+ getCurrentConnector(): AbstractNetworkConnector<TransactionType>;
25
+ /**
26
+ * Execute an operation using the configured strategy
27
+ * @param operation The operation to execute
28
+ * @returns The result of the operation
29
+ */
30
+ private executeWithStrategy;
31
+ /**
32
+ * Set the strategy to use for connector selection
33
+ * @param strategy The strategy to use
34
+ */
35
+ setStrategy(strategy: ConnectorSelectionStrategy<TransactionType>): void;
36
+ /**
37
+ * Get a block at a specific height
38
+ * @param height The height of the block to get
39
+ * @returns The block at the specified height
40
+ */
41
+ getBlockAtHeight: (height: number) => Promise<Block>;
42
+ /**
43
+ * Get the current height of the blockchain
44
+ * @returns The current height
45
+ */
46
+ getCurrentHeight: () => Promise<number>;
47
+ /**
48
+ * Get all transactions in a block
49
+ * @param blockHash The hash of the block to get transactions from
50
+ * @returns Array of transactions in the block
51
+ */
52
+ getBlockTxs: (blockHash: string) => Promise<Array<TransactionType>>;
53
+ /**
54
+ * Get the number of available connectors
55
+ * @returns The number of connectors
56
+ */
57
+ getConnectorCount(): number;
58
+ /**
59
+ * Remove a connector at the specified index
60
+ * @param index The index of the connector to remove
61
+ */
62
+ removeConnector(index: number): void;
63
+ }
64
+ //# sourceMappingURL=NetworkConnectorManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NetworkConnectorManager.d.ts","sourceRoot":"","sources":["../../../lib/scanner/network/NetworkConnectorManager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,KAAK,EACN,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,0BAA0B,EAE3B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,cAAc,EAAe,MAAM,+BAA+B,CAAC;AAE5E;;;GAGG;AACH,qBAAa,uBAAuB,CAAC,eAAe,CAClD,YAAW,wBAAwB,CAAC,eAAe,CAAC;IAMlD,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,MAAM;IALhB,OAAO,CAAC,UAAU,CAAmD;IACrE,OAAO,CAAC,qBAAqB,CAAS;gBAG5B,QAAQ,GAAE,0BAA0B,CAAC,eAAe,CAA2C,EAC/F,MAAM,GAAE,cAAkC;IAQpD;;;OAGG;IACI,YAAY,CACjB,SAAS,EAAE,wBAAwB,CAAC,eAAe,CAAC,GACnD,IAAI;IAOP;;;;OAIG;IACH,mBAAmB,IAAI,wBAAwB,CAAC,eAAe,CAAC;IAQhE;;;;OAIG;YACW,mBAAmB;IA8CjC;;;OAGG;IACI,WAAW,CAChB,QAAQ,EAAE,0BAA0B,CAAC,eAAe,CAAC,GACpD,IAAI;IAKP;;;;OAIG;IACH,gBAAgB,WAAkB,MAAM,KAAG,QAAQ,KAAK,CAAC,CAIvD;IAEF;;;OAGG;IACH,gBAAgB,QAAa,QAAQ,MAAM,CAAC,CAI1C;IAEF;;;;OAIG;IACH,WAAW,cAAqB,MAAM,KAAG,QAAQ,MAAM,eAAe,CAAC,CAAC,CAItE;IAEF;;;OAGG;IACI,iBAAiB,IAAI,MAAM;IAMlC;;;OAGG;IACI,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;CAU5C"}