@my-packages-changeit/abstract-scanner 2.0.3

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 (73) hide show
  1. package/CHANGELOG.md +135 -0
  2. package/README.md +49 -0
  3. package/dist/entities/blockEntity.d.ts +17 -0
  4. package/dist/entities/blockEntity.d.ts.map +1 -0
  5. package/dist/entities/blockEntity.js +78 -0
  6. package/dist/entities/extractorStatusEntity.d.ts +7 -0
  7. package/dist/entities/extractorStatusEntity.d.ts.map +1 -0
  8. package/dist/entities/extractorStatusEntity.js +37 -0
  9. package/dist/index.d.ts +11 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +10 -0
  12. package/dist/migrations/index.d.ts +7 -0
  13. package/dist/migrations/index.d.ts.map +1 -0
  14. package/dist/migrations/index.js +31 -0
  15. package/dist/migrations/postgres/1688545690867-migration.d.ts +7 -0
  16. package/dist/migrations/postgres/1688545690867-migration.d.ts.map +1 -0
  17. package/dist/migrations/postgres/1688545690867-migration.js +30 -0
  18. package/dist/migrations/postgres/1713803486477-migration.d.ts +7 -0
  19. package/dist/migrations/postgres/1713803486477-migration.d.ts.map +1 -0
  20. package/dist/migrations/postgres/1713803486477-migration.js +20 -0
  21. package/dist/migrations/postgres/1718789786123-migration.d.ts +7 -0
  22. package/dist/migrations/postgres/1718789786123-migration.d.ts.map +1 -0
  23. package/dist/migrations/postgres/1718789786123-migration.js +12 -0
  24. package/dist/migrations/postgres/1722697954558-migration.d.ts +7 -0
  25. package/dist/migrations/postgres/1722697954558-migration.d.ts.map +1 -0
  26. package/dist/migrations/postgres/1722697954558-migration.js +52 -0
  27. package/dist/migrations/postgres/1746701087567-migration.d.ts +7 -0
  28. package/dist/migrations/postgres/1746701087567-migration.d.ts.map +1 -0
  29. package/dist/migrations/postgres/1746701087567-migration.js +32 -0
  30. package/dist/migrations/postgres/1747657653564-migration.d.ts +7 -0
  31. package/dist/migrations/postgres/1747657653564-migration.d.ts.map +1 -0
  32. package/dist/migrations/postgres/1747657653564-migration.js +134 -0
  33. package/dist/migrations/sqlite/1688555497475-migration.d.ts +7 -0
  34. package/dist/migrations/sqlite/1688555497475-migration.d.ts.map +1 -0
  35. package/dist/migrations/sqlite/1688555497475-migration.js +29 -0
  36. package/dist/migrations/sqlite/1713786682123-migration.d.ts +7 -0
  37. package/dist/migrations/sqlite/1713786682123-migration.d.ts.map +1 -0
  38. package/dist/migrations/sqlite/1713786682123-migration.js +20 -0
  39. package/dist/migrations/sqlite/1718789744123-migration.d.ts +7 -0
  40. package/dist/migrations/sqlite/1718789744123-migration.d.ts.map +1 -0
  41. package/dist/migrations/sqlite/1718789744123-migration.js +12 -0
  42. package/dist/migrations/sqlite/1722697111974-migration.d.ts +7 -0
  43. package/dist/migrations/sqlite/1722697111974-migration.d.ts.map +1 -0
  44. package/dist/migrations/sqlite/1722697111974-migration.js +112 -0
  45. package/dist/migrations/sqlite/1746701087234-migration.d.ts +7 -0
  46. package/dist/migrations/sqlite/1746701087234-migration.d.ts.map +1 -0
  47. package/dist/migrations/sqlite/1746701087234-migration.js +32 -0
  48. package/dist/migrations/sqlite/1747655941239-migration.d.ts +7 -0
  49. package/dist/migrations/sqlite/1747655941239-migration.d.ts.map +1 -0
  50. package/dist/migrations/sqlite/1747655941239-migration.js +134 -0
  51. package/dist/scanner/abstract/generalScanner.d.ts +78 -0
  52. package/dist/scanner/abstract/generalScanner.d.ts.map +1 -0
  53. package/dist/scanner/abstract/generalScanner.js +210 -0
  54. package/dist/scanner/abstract/scanner.d.ts +49 -0
  55. package/dist/scanner/abstract/scanner.d.ts.map +1 -0
  56. package/dist/scanner/abstract/scanner.js +142 -0
  57. package/dist/scanner/abstract/webSocketScanner.d.ts +29 -0
  58. package/dist/scanner/abstract/webSocketScanner.d.ts.map +1 -0
  59. package/dist/scanner/abstract/webSocketScanner.js +90 -0
  60. package/dist/scanner/action.d.ts +83 -0
  61. package/dist/scanner/action.d.ts.map +1 -0
  62. package/dist/scanner/action.js +251 -0
  63. package/dist/scanner/interfaces.d.ts +13 -0
  64. package/dist/scanner/interfaces.d.ts.map +1 -0
  65. package/dist/scanner/interfaces.js +2 -0
  66. package/dist/scanner/network/connectorSelectionStrategies.d.ts +27 -0
  67. package/dist/scanner/network/connectorSelectionStrategies.d.ts.map +1 -0
  68. package/dist/scanner/network/connectorSelectionStrategies.js +22 -0
  69. package/dist/scanner/network/networkConnectorManager.d.ts +65 -0
  70. package/dist/scanner/network/networkConnectorManager.d.ts.map +1 -0
  71. package/dist/scanner/network/networkConnectorManager.js +126 -0
  72. package/dist/tsconfig.tsbuildinfo +1 -0
  73. package/package.json +46 -0
@@ -0,0 +1,142 @@
1
+ import { difference, remove } from 'lodash-es';
2
+ import { DummyLogger } from '@rosen-bridge/abstract-logger';
3
+ import { Mutex } from '@rosen-bridge/semaphore';
4
+ export class AbstractScanner {
5
+ action;
6
+ extractors;
7
+ newExtractors;
8
+ logger;
9
+ initializeMutex;
10
+ constructor(logger) {
11
+ this.extractors = [];
12
+ this.newExtractors = [];
13
+ this.logger = logger ? logger : new DummyLogger();
14
+ this.initializeMutex = new Mutex();
15
+ }
16
+ /**
17
+ * fork blocks from specific height from scanner.
18
+ * @param height: selected height
19
+ */
20
+ forkBlock = async (height) => {
21
+ let lastBlock = await this.action.getLastSavedBlock();
22
+ while (lastBlock && lastBlock.height >= height) {
23
+ this.logger.debug(`Reverting block ${lastBlock.hash} at height ${lastBlock.height}`);
24
+ await this.action.revertBlockStatus(lastBlock.height, lastBlock.parentHash, this.extractors.map((e) => e.getId()));
25
+ for (const extractor of this.extractors) {
26
+ await extractor.forkBlock(lastBlock.hash);
27
+ }
28
+ await this.action.removeBlocksFromHeight(lastBlock.height);
29
+ lastBlock = await this.action.getBlockAtHeight(lastBlock.height - 1);
30
+ }
31
+ };
32
+ /**
33
+ * process a block and all of its transactions. store any information into database
34
+ * @param block: selected block
35
+ * @param transactions: list of transaction for selected block
36
+ */
37
+ processBlockTransactions = async (block, transactions) => {
38
+ const savedBlock = await this.action.saveBlock(block);
39
+ if (typeof savedBlock === 'boolean') {
40
+ return false;
41
+ }
42
+ let success = true;
43
+ for (const extractor of this.extractors) {
44
+ if (!(await extractor.processTransactions(transactions, savedBlock))) {
45
+ success = false;
46
+ break;
47
+ }
48
+ }
49
+ if (success &&
50
+ (await this.action.updateBlockStatus(block.height, block.hash, this.extractors.map((e) => e.getId())))) {
51
+ return savedBlock;
52
+ }
53
+ return false;
54
+ };
55
+ /**
56
+ * register a nre extractor to scanner.
57
+ * @param extractor
58
+ */
59
+ registerExtractor = async (extractor) => {
60
+ const notRegisteredIn = (extractors) => extractors.filter((extractorItem) => extractorItem.getId() === extractor.getId()).length === 0;
61
+ const release = await this.initializeMutex.acquire();
62
+ if (notRegisteredIn(this.extractors) &&
63
+ notRegisteredIn(this.newExtractors)) {
64
+ this.newExtractors.push(extractor);
65
+ }
66
+ else {
67
+ this.logger.warn(`Extractor with id ${extractor.getId()} is already registered`);
68
+ }
69
+ release();
70
+ };
71
+ /**
72
+ * remove an extractor from scanner
73
+ * @param extractor
74
+ */
75
+ removeExtractor = async (extractor) => {
76
+ const removeFn = (ex) => ex.getId() === extractor.getId();
77
+ const release = await this.initializeMutex.acquire();
78
+ remove(this.extractors, removeFn);
79
+ remove(this.newExtractors, removeFn);
80
+ release();
81
+ };
82
+ /**
83
+ * Initialize all specified extractors and store the updated status
84
+ * @param extractorIds
85
+ * @param height
86
+ */
87
+ initializeExtractors = async (extractorIds, block) => {
88
+ const allExtractors = [...this.extractors, ...this.newExtractors];
89
+ const initRequiredExtractors = allExtractors.filter((extractor) => extractorIds.includes(extractor.getId()));
90
+ for (const extractor of initRequiredExtractors) {
91
+ this.logger.info(`Initializing [${extractor.getId()}] boxes`);
92
+ await extractor.initializeData(block);
93
+ await this.action.updateOrInsertExtractorStatus(extractor.getId(), block.height, block.hash);
94
+ this.logger.debug(`Initialization finished for [${extractor.getId()}]`);
95
+ }
96
+ };
97
+ /**
98
+ * Initializes the extractors if they're not synced or not initialized yet,
99
+ * and update the active extractors list
100
+ * @param block
101
+ */
102
+ verifyExtractorsInitialization = async (block) => {
103
+ const getIds = (extractors) => {
104
+ return extractors.map((extractor) => extractor.getId());
105
+ };
106
+ this.logger.debug(`Initializing extractors for block [${block.height}]`);
107
+ const release = await this.initializeMutex.acquire();
108
+ try {
109
+ const extractorsStatus = await this.action.getExtractorsStatus([
110
+ ...getIds(this.extractors),
111
+ ...getIds(this.newExtractors),
112
+ ]);
113
+ this.logger.debug(`Stored extractors status are [${JSON.stringify(extractorsStatus)}]`);
114
+ // Find extractors not synced with the latest height
115
+ const notSyncedExtractorIds = extractorsStatus
116
+ .filter((es) => es.updateBlockHash != block.hash)
117
+ .map((es) => es.extractorId);
118
+ if (notSyncedExtractorIds.length > 0)
119
+ this.logger.debug(`Old not synced extractors are ${notSyncedExtractorIds}`);
120
+ // Find new extractors not available in database
121
+ const storedExtractorIds = extractorsStatus.map((es) => es.extractorId);
122
+ const newRegisteredExtractorIds = difference(getIds(this.newExtractors), storedExtractorIds);
123
+ if (newRegisteredExtractorIds.length > 0)
124
+ this.logger.debug(`New registered extractors are ${newRegisteredExtractorIds}`);
125
+ // Initialize required extractors
126
+ const initRequiredExtractors = [
127
+ ...newRegisteredExtractorIds,
128
+ ...notSyncedExtractorIds,
129
+ ];
130
+ if (initRequiredExtractors.length > 0) {
131
+ this.logger.info(`Initializing ${initRequiredExtractors.length} extractor(s) for [${this.name()}]`, { initRequiredExtractors });
132
+ await this.initializeExtractors(initRequiredExtractors, block);
133
+ }
134
+ this.extractors.push(...this.newExtractors);
135
+ this.newExtractors = [];
136
+ }
137
+ finally {
138
+ release();
139
+ }
140
+ };
141
+ }
142
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nhbm5lci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9zY2FubmVyL2Fic3RyYWN0L3NjYW5uZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFHL0MsT0FBTyxFQUFrQixXQUFXLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUc1RSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFJaEQsTUFBTSxPQUFnQixlQUFlO0lBQ25DLE1BQU0sQ0FBZ0I7SUFDdEIsVUFBVSxDQUEyRDtJQUNyRSxhQUFhLENBQTJEO0lBQ3hFLE1BQU0sQ0FBaUI7SUFDdkIsZUFBZSxDQUFRO0lBRXZCLFlBQVksTUFBdUI7UUFDakMsSUFBSSxDQUFDLFVBQVUsR0FBRyxFQUFFLENBQUM7UUFDckIsSUFBSSxDQUFDLGFBQWEsR0FBRyxFQUFFLENBQUM7UUFDeEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxXQUFXLEVBQUUsQ0FBQztRQUNsRCxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksS0FBSyxFQUFFLENBQUM7SUFDckMsQ0FBQztJQUlEOzs7T0FHRztJQUNPLFNBQVMsR0FBRyxLQUFLLEVBQUUsTUFBYyxFQUFFLEVBQUU7UUFDN0MsSUFBSSxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDdEQsT0FBTyxTQUFTLElBQUksU0FBUyxDQUFDLE1BQU0sSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUMvQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FDZixtQkFBbUIsU0FBUyxDQUFDLElBQUksY0FBYyxTQUFTLENBQUMsTUFBTSxFQUFFLENBQ2xFLENBQUM7WUFDRixNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsaUJB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QkFBcUIsRUFBRSxDQUN6RCxDQUFDO1lBQ0osZ0RBQWdEO1lBQ2hELE1BQU0sa0JBQWtCLEdBQUcsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDeEUsTUFBTSx5QkFBeUIsR0FBRyxVQUFVLENBQzFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzFCLGtCQUFrQixDQUNuQixDQUFDO1lBQ0YsSUFBSSx5QkFBeUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQztnQkFDdEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQ2YsaUNBQWlDLHlCQUF5QixFQUFFLENBQzdELENBQUM7WUFDSixpQ0FBaUM7WUFDakMsTUFBTSxzQkFBc0IsR0FBRztnQkFDN0IsR0FBRyx5QkFBeUI7Z0JBQzVCLEdBQUcscUJBQXFCO2FBQ3pCLENBQUM7WUFDRixJQUFJLHNCQUFzQixDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDdEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ2QsZ0JBQ0Usc0JBQXNCLENBQUMsTUFDekIsc0JBQXNCLElBQUksQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUNwQyxFQUFFLHNCQUFzQixFQUFFLENBQzNCLENBQUM7Z0JBQ0YsTUFBTSxJQUFJLENBQUMsb0JBQW9CLENBQUMsc0JBQXNCLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDakUsQ0FBQztZQUNELElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQzVDLElBQUksQ0FBQyxhQUFhLEdBQUcsRUFBRSxDQUFDO1FBQzFCLENBQUM7Z0JBQVMsQ0FBQztZQUNULE9BQU8sRUFBRSxDQUFDO1FBQ1osQ0FBQztJQUNILENBQUMsQ0FBQztDQUNIIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZGlmZmVyZW5jZSwgcmVtb3ZlIH0gZnJvbSAnbG9kYXNoLWVzJztcblxuaW1wb3J0IHsgQWJzdHJhY3RFeHRyYWN0b3IgfSBmcm9tICdAcm9zZW4tYnJpZGdlL2Fic3RyYWN0LWV4dHJhY3Rvcic7XG5pbXBvcnQgeyBBYnN0cmFjdExvZ2dlciwgRHVtbXlMb2dnZXIgfSBmcm9tICdAcm9zZW4tYnJpZGdlL2Fic3RyYWN0LWxvZ2dlcic7XG5pbXBvcnQgeyBPYmplY3RMaXRlcmFsIH0gZnJvbSAnQHJvc2VuLWJyaWRnZS9leHRlbmRlZC10eXBlb3JtJztcbmltcG9ydCB7IEJsb2NrLCBCbG9ja0luZm8gfSBmcm9tICdAcm9zZW4tYnJpZGdlL3NjYW5uZXItaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBNdXRleCB9IGZyb20gJ0Byb3Nlbi1icmlkZ2Uvc2VtYXBob3JlJztcblxuaW1wb3J0IHsgQmxvY2tEYkFjdGlvbiB9IGZyb20gJy4uL2FjdGlvbic7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdFNjYW5uZXI8VHJhbnNhY3Rpb25UeXBlPiB7XG4gIGFjdGlvbjogQmxvY2tEYkFjdGlvbjtcbiAgZXh0cmFjdG9yczogQXJyYXk8QWJzdHJhY3RFeHRyYWN0b3I8VHJhbnNhY3Rpb25UeXBlLCBPYmplY3RMaXRlcmFsPj47XG4gIG5ld0V4dHJhY3RvcnM6IEFycmF5PEFic3RyYWN0RXh0cmFjdG9yPFRyYW5zYWN0aW9uVHlwZSwgT2JqZWN0TGl0ZXJhbD4+O1xuICBsb2dnZXI6IEFic3RyYWN0TG9nZ2VyO1xuICBpbml0aWFsaXplTXV0ZXg6IE11dGV4O1xuXG4gIGNvbnN0cnVjdG9yKGxvZ2dlcj86IEFic3RyYWN0TG9nZ2VyKSB7XG4gICAgdGhpcy5leHRyYWN0b3JzID0gW107XG4gICAgdGhpcy5uZXdFeHRyYWN0b3JzID0gW107XG4gICAgdGhpcy5sb2dnZXIgPSBsb2dnZXIgPyBsb2dnZXIgOiBuZXcgRHVtbXlMb2dnZXIoKTtcbiAgICB0aGlzLmluaXRpYWxpemVNdXRleCA9IG5ldyBNdXRleCgpO1xuICB9XG5cbiAgYWJzdHJhY3QgbmFtZTogKCkgPT4gc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBmb3JrIGJsb2NrcyBmcm9tIHNwZWNpZmljIGhlaWdodCBmcm9tIHNjYW5uZXIuXG4gICAqIEBwYXJhbSBoZWlnaHQ6IHNlbGVjdGVkIGhlaWdodFxuICAgKi9cbiAgcHJvdGVjdGVkIGZvcmtCbG9jayA9IGFzeW5jIChoZWlnaHQ6IG51bWJlcikgPT4ge1xuICAgIGxldCBsYXN0QmxvY2sgPSBhd2FpdCB0aGlzLmFjdGlvbi5nZXRMYXN0U2F2ZWRCbG9jaygpO1xuICAgIHdoaWxlIChsYXN0QmxvY2sgJiYgbGFzdEJsb2NrLmhlaWdodCA+PSBoZWlnaHQpIHtcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKFxuICAgICAgICBgUmV2ZXJ0aW5nIGJsb2NrICR7bGFzdEJsb2NrLmhhc2h9IGF0IGhlaWdodCAke2xhc3RCbG9jay5oZWlnaHR9YCxcbiAgICAgICk7XG4gICAgICBhd2FpdCB0aGlzLmFjdGlvbi5yZXZlcnRCbG9ja1N0YXR1cyhcbiAgICAgICAgbGFzdEJsb2NrLmhlaWdodCxcbiAgICAgICAgbGFzdEJsb2NrLnBhcmVudEhhc2gsXG4gICAgICAgIHRoaXMuZXh0cmFjdG9ycy5tYXAoKGUpID0+IGUuZ2V0SWQoKSksXG4gICAgICApO1xuICAgICAgZm9yIChjb25zdCBleHRyYWN0b3Igb2YgdGhpcy5leHRyYWN0b3JzKSB7XG4gICAgICAgIGF3YWl0IGV4dHJhY3Rvci5mb3JrQmxvY2sobGFzdEJsb2NrLmhhc2gpO1xuICAgICAgfVxuICAgICAgYXdhaXQgdGhpcy5hY3Rpb24ucmVtb3ZlQmxvY2tzRnJvbUhlaWdodChsYXN0QmxvY2suaGVpZ2h0KTtcbiAgICAgIGxhc3RCbG9jayA9IGF3YWl0IHRoaXMuYWN0aW9uLmdldEJsb2NrQXRIZWlnaHQobGFzdEJsb2NrLmhlaWdodCAtIDEpO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogcHJvY2VzcyBhIGJsb2NrIGFuZCBhbGwgb2YgaXRzIHRyYW5zYWN0aW9ucy4gc3RvcmUgYW55IGluZm9ybWF0aW9uIGludG8gZGF0YWJhc2VcbiAgICogQHBhcmFtIGJsb2NrOiBzZWxlY3RlZCBibG9ja1xuICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25zOiBsaXN0IG9mIHRyYW5zYWN0aW9uIGZvciBzZWxlY3RlZCBibG9ja1xuICAgKi9cbiAgcHJvdGVjdGVkIHByb2Nlc3NCbG9ja1RyYW5zYWN0aW9ucyA9IGFzeW5jIChcbiAgICBibG9jazogQmxvY2ssXG4gICAgdHJhbnNhY3Rpb25zOiBBcnJheTxUcmFuc2FjdGlvblR5cGU+LFxuICApID0+IHtcbiAgICBjb25zdCBzYXZlZEJsb2NrID0gYXdhaXQgdGhpcy5hY3Rpb24uc2F2ZUJsb2NrKGJsb2NrKTtcbiAgICBpZiAodHlwZW9mIHNhdmVkQmxvY2sgPT09ICdib29sZWFuJykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBsZXQgc3VjY2VzcyA9IHRydWU7XG4gICAgZm9yIChjb25zdCBleHRyYWN0b3Igb2YgdGhpcy5leHRyYWN0b3JzKSB7XG4gICAgICBpZiAoIShhd2FpdCBleHRyYWN0b3IucHJvY2Vzc1RyYW5zYWN0aW9ucyh0cmFuc2FjdGlvbnMsIHNhdmVkQmxvY2spKSkge1xuICAgICAgICBzdWNjZXNzID0gZmFsc2U7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHN1Y2Nlc3MgJiZcbiAgICAgIChhd2FpdCB0aGlzLmFjdGlvbi51cGRhdGVCbG9ja1N0YXR1cyhcbiAgICAgICAgYmxvY2suaGVpZ2h0LFxuICAgICAgICBibG9jay5oYXNoLFxuICAgICAgICB0aGlzLmV4dHJhY3RvcnMubWFwKChlKSA9PiBlLmdldElkKCkpLFxuICAgICAgKSlcbiAgICApIHtcbiAgICAgIHJldHVybiBzYXZlZEJsb2NrO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH07XG5cbiAgLyoqXG4gICAqIHJlZ2lzdGVyIGEgbnJlIGV4dHJhY3RvciB0byBzY2FubmVyLlxuICAgKiBAcGFyYW0gZXh0cmFjdG9yXG4gICAqL1xuICByZWdpc3RlckV4dHJhY3RvciA9IGFzeW5jIChcbiAgICBleHRyYWN0b3I6IEFic3RyYWN0RXh0cmFjdG9yPFRyYW5zYWN0aW9uVHlwZSwgT2JqZWN0TGl0ZXJhbD4sXG4gICk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGNvbnN0IG5vdFJlZ2lzdGVyZWRJbiA9IChcbiAgICAgIGV4dHJhY3RvcnM6IEFycmF5PEFic3RyYWN0RXh0cmFjdG9yPFRyYW5zYWN0aW9uVHlwZSwgT2JqZWN0TGl0ZXJhbD4+LFxuICAgICkgPT5cbiAgICAgIGV4dHJhY3RvcnMuZmlsdGVyKFxuICAgICAgICAoZXh0cmFjdG9ySXRlbSkgPT4gZXh0cmFjdG9ySXRlbS5nZXRJZCgpID09PSBleHRyYWN0b3IuZ2V0SWQoKSxcbiAgICAgICkubGVuZ3RoID09PSAwO1xuICAgIGNvbnN0IHJlbGVhc2UgPSBhd2FpdCB0aGlzLmluaXRpYWxpemVNdXRleC5hY3F1aXJlKCk7XG4gICAgaWYgKFxuICAgICAgbm90UmVnaXN0ZXJlZEluKHRoaXMuZXh0cmFjdG9ycykgJiZcbiAgICAgIG5vdFJlZ2lzdGVyZWRJbih0aGlzLm5ld0V4dHJhY3RvcnMpXG4gICAgKSB7XG4gICAgICB0aGlzLm5ld0V4dHJhY3RvcnMucHVzaChleHRyYWN0b3IpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxvZ2dlci53YXJuKFxuICAgICAgICBgRXh0cmFjdG9yIHdpdGggaWQgJHtleHRyYWN0b3IuZ2V0SWQoKX0gaXMgYWxyZWFkeSByZWdpc3RlcmVkYCxcbiAgICAgICk7XG4gICAgfVxuICAgIHJlbGVhc2UoKTtcbiAgfTtcblxuICAvKipcbiAgICogcmVtb3ZlIGFuIGV4dHJhY3RvciBmcm9tIHNjYW5uZXJcbiAgICogQHBhcmFtIGV4dHJhY3RvclxuICAgKi9cbiAgcmVtb3ZlRXh0cmFjdG9yID0gYXN5bmMgKFxuICAgIGV4dHJhY3RvcjogQWJzdHJhY3RFeHRyYWN0b3I8VHJhbnNhY3Rpb25UeXBlLCBPYmplY3RMaXRlcmFsPixcbiAgKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgY29uc3QgcmVtb3ZlRm4gPSAoZXg6IEFic3RyYWN0RXh0cmFjdG9yPFRyYW5zYWN0aW9uVHlwZSwgT2JqZWN0TGl0ZXJhbD4pID0+XG4gICAgICBleC5nZXRJZCgpID09PSBleHRyYWN0b3IuZ2V0SWQoKTtcblxuICAgIGNvbnN0IHJlbGVhc2UgPSBhd2FpdCB0aGlzLmluaXRpYWxpemVNdXRleC5hY3F1aXJlKCk7XG4gICAgcmVtb3ZlKHRoaXMuZXh0cmFjdG9ycywgcmVtb3ZlRm4pO1xuICAgIHJlbW92ZSh0aGlzLm5ld0V4dHJhY3RvcnMsIHJlbW92ZUZuKTtcbiAgICByZWxlYXNlKCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemUgYWxsIHNwZWNpZmllZCBleHRyYWN0b3JzIGFuZCBzdG9yZSB0aGUgdXBkYXRlZCBzdGF0dXNcbiAgICogQHBhcmFtIGV4dHJhY3Rvcklkc1xuICAgKiBAcGFyYW0gaGVpZ2h0XG4gICAqL1xuICBwcml2YXRlIGluaXRpYWxpemVFeHRyYWN0b3JzID0gYXN5bmMgKFxuICAgIGV4dHJhY3Rvcklkczogc3RyaW5nW10sXG4gICAgYmxvY2s6IEJsb2NrSW5mbyxcbiAgKSA9PiB7XG4gICAgY29uc3QgYWxsRXh0cmFjdG9ycyA9IFsuLi50aGlzLmV4dHJhY3RvcnMsIC4uLnRoaXMubmV3RXh0cmFjdG9yc107XG4gICAgY29uc3QgaW5pdFJlcXVpcmVkRXh0cmFjdG9ycyA9IGFsbEV4dHJhY3RvcnMuZmlsdGVyKChleHRyYWN0b3IpID0+XG4gICAgICBleHRyYWN0b3JJZHMuaW5jbHVkZXMoZXh0cmFjdG9yLmdldElkKCkpLFxuICAgICk7XG4gICAgZm9yIChjb25zdCBleHRyYWN0b3Igb2YgaW5pdFJlcXVpcmVkRXh0cmFjdG9ycykge1xuICAgICAgdGhpcy5sb2dnZXIuaW5mbyhgSW5pdGlhbGl6aW5nIFske2V4dHJhY3Rvci5nZXRJZCgpfV0gYm94ZXNgKTtcbiAgICAgIGF3YWl0IGV4dHJhY3Rvci5pbml0aWFsaXplRGF0YShibG9jayk7XG4gICAgICBhd2FpdCB0aGlzLmFjdGlvbi51cGRhdGVPckluc2VydEV4dHJhY3RvclN0YXR1cyhcbiAgICAgICAgZXh0cmFjdG9yLmdldElkKCksXG4gICAgICAgIGJsb2NrLmhlaWdodCxcbiAgICAgICAgYmxvY2suaGFzaCxcbiAgICAgICk7XG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgSW5pdGlhbGl6YXRpb24gZmluaXNoZWQgZm9yIFske2V4dHJhY3Rvci5nZXRJZCgpfV1gKTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemVzIHRoZSBleHRyYWN0b3JzIGlmIHRoZXkncmUgbm90IHN5bmNlZCBvciBub3QgaW5pdGlhbGl6ZWQgeWV0LFxuICAgKiBhbmQgdXBkYXRlIHRoZSBhY3RpdmUgZXh0cmFjdG9ycyBsaXN0XG4gICAqIEBwYXJhbSBibG9ja1xuICAgKi9cbiAgcHJvdGVjdGVkIHZlcmlmeUV4dHJhY3RvcnNJbml0aWFsaXphdGlvbiA9IGFzeW5jIChibG9jazogQmxvY2tJbmZvKSA9PiB7XG4gICAgY29uc3QgZ2V0SWRzID0gKFxuICAgICAgZXh0cmFjdG9yczogQXJyYXk8QWJzdHJhY3RFeHRyYWN0b3I8VHJhbnNhY3Rpb25UeXBlLCBPYmplY3RMaXRlcmFsPj4sXG4gICAgKSA9PiB7XG4gICAgICByZXR1cm4gZXh0cmFjdG9ycy5tYXAoKGV4dHJhY3RvcikgPT4gZXh0cmFjdG9yLmdldElkKCkpO1xuICAgIH07XG4gICAgdGhpcy5sb2dnZXIuZGVidWcoYEluaXRpYWxpemluZyBleHRyYWN0b3JzIGZvciBibG9jayBbJHtibG9jay5oZWlnaHR9XWApO1xuICAgIGNvbnN0IHJlbGVhc2UgPSBhd2FpdCB0aGlzLmluaXRpYWxpemVNdXRleC5hY3F1aXJlKCk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGV4dHJhY3RvcnNTdGF0dXMgPSBhd2FpdCB0aGlzLmFjdGlvbi5nZXRFeHRyYWN0b3JzU3RhdHVzKFtcbiAgICAgICAgLi4uZ2V0SWRzKHRoaXMuZXh0cmFjdG9ycyksXG4gICAgICAgIC4uLmdldElkcyh0aGlzLm5ld0V4dHJhY3RvcnMpLFxuICAgICAgXSk7XG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgYFN0b3JlZCBleHRyYWN0b3JzIHN0YXR1cyBhcmUgWyR7SlNPTi5zdHJpbmdpZnkoZXh0cmFjdG9yc1N0YXR1cyl9XWAsXG4gICAgICApO1xuICAgICAgLy8gRmluZCBleHRyYWN0b3JzIG5vdCBzeW5jZWQgd2l0aCB0aGUgbGF0ZXN0IGhlaWdodFxuICAgICAgY29uc3Qgbm90U3luY2VkRXh0cmFjdG9ySWRzID0gZXh0cmFjdG9yc1N0YXR1c1xuICAgICAgICAuZmlsdGVyKChlcykgPT4gZXMudXBkYXRlQmxvY2tIYXNoICE9IGJsb2NrLmhhc2gpXG4gICAgICAgIC5tYXAoKGVzKSA9PiBlcy5leHRyYWN0b3JJZCk7XG4gICAgICBpZiAobm90U3luY2VkRXh0cmFjdG9ySWRzLmxlbmd0aCA+IDApXG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKFxuICAgICAgICAgIGBPbGQgbm90IHN5bmNlZCBleHRyYWN0b3JzIGFyZSAke25vdFN5bmNlZEV4dHJhY3Rvcklkc31gLFxuICAgICAgICApO1xuICAgICAgLy8gRmluZCBuZXcgZXh0cmFjdG9ycyBub3QgYXZhaWxhYmxlIGluIGRhdGFiYXNlXG4gICAgICBjb25zdCBzdG9yZWRFeHRyYWN0b3JJZHMgPSBleHRyYWN0b3JzU3RhdHVzLm1hcCgoZXMpID0+IGVzLmV4dHJhY3RvcklkKTtcbiAgICAgIGNvbnN0IG5ld1JlZ2lzdGVyZWRFeHRyYWN0b3JJZHMgPSBkaWZmZXJlbmNlKFxuICAgICAgICBnZXRJZHModGhpcy5uZXdFeHRyYWN0b3JzKSxcbiAgICAgICAgc3RvcmVkRXh0cmFjdG9ySWRzLFxuICAgICAgKTtcbiAgICAgIGlmIChuZXdSZWdpc3RlcmVkRXh0cmFjdG9ySWRzLmxlbmd0aCA+IDApXG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKFxuICAgICAgICAgIGBOZXcgcmVnaXN0ZXJlZCBleHRyYWN0b3JzIGFyZSAke25ld1JlZ2lzdGVyZWRFeHRyYWN0b3JJZHN9YCxcbiAgICAgICAgKTtcbiAgICAgIC8vIEluaXRpYWxpemUgcmVxdWlyZWQgZXh0cmFjdG9yc1xuICAgICAgY29uc3QgaW5pdFJlcXVpcmVkRXh0cmFjdG9ycyA9IFtcbiAgICAgICAgLi4ubmV3UmVnaXN0ZXJlZEV4dHJhY3RvcklkcyxcbiAgICAgICAgLi4ubm90U3luY2VkRXh0cmFjdG9ySWRzLFxuICAgICAgXTtcbiAgICAgIGlmIChpbml0UmVxdWlyZWRFeHRyYWN0b3JzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuaW5mbyhcbiAgICAgICAgICBgSW5pdGlhbGl6aW5nICR7XG4gICAgICAgICAgICBpbml0UmVxdWlyZWRFeHRyYWN0b3JzLmxlbmd0aFxuICAgICAgICAgIH0gZXh0cmFjdG9yKHMpIGZvciBbJHt0aGlzLm5hbWUoKX1dYCxcbiAgICAgICAgICB7IGluaXRSZXF1aXJlZEV4dHJhY3RvcnMgfSxcbiAgICAgICAgKTtcbiAgICAgICAgYXdhaXQgdGhpcy5pbml0aWFsaXplRXh0cmFjdG9ycyhpbml0UmVxdWlyZWRFeHRyYWN0b3JzLCBibG9jayk7XG4gICAgICB9XG4gICAgICB0aGlzLmV4dHJhY3RvcnMucHVzaCguLi50aGlzLm5ld0V4dHJhY3RvcnMpO1xuICAgICAgdGhpcy5uZXdFeHRyYWN0b3JzID0gW107XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHJlbGVhc2UoKTtcbiAgICB9XG4gIH07XG59XG4iXX0=
@@ -0,0 +1,29 @@
1
+ import { AbstractLogger } from '@rosen-bridge/abstract-logger';
2
+ import { Block } from '@rosen-bridge/scanner-interfaces';
3
+ import { Mutex } from '@rosen-bridge/semaphore';
4
+ import { AbstractScanner } from './scanner';
5
+ declare abstract class WebSocketScanner<TransactionType> extends AbstractScanner<TransactionType> {
6
+ protected scannerName: string;
7
+ protected suffix?: string | undefined;
8
+ readonly maxTryBlock: number;
9
+ protected mutex: Mutex;
10
+ protected constructor(scannerName: string, logger?: AbstractLogger, maxTryBlock?: number, suffix?: string | undefined);
11
+ name: () => string;
12
+ abstract start: () => Promise<void>;
13
+ abstract stop: () => Promise<void>;
14
+ protected tryRunningFunction: (fn: () => Promise<boolean>, msg: string, releaseMutex: () => void) => Promise<boolean>;
15
+ /**
16
+ * Handle new block arrived.
17
+ * save block and its transactions.
18
+ * @param block
19
+ * @param transactions
20
+ */
21
+ protected stepForward: (block: Block, transactions: Array<TransactionType>) => Promise<void>;
22
+ /**
23
+ * Handle forking a block
24
+ * @param block
25
+ */
26
+ protected stepBackward: (block: Block) => Promise<void>;
27
+ }
28
+ export { WebSocketScanner };
29
+ //# sourceMappingURL=webSocketScanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webSocketScanner.d.ts","sourceRoot":"","sources":["../../../lib/scanner/abstract/webSocketScanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,KAAK,EAAE,MAAM,kCAAkC,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAEhD,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAI5C,uBAAe,gBAAgB,CAC7B,eAAe,CACf,SAAQ,eAAe,CAAC,eAAe,CAAC;IAMtC,SAAS,CAAC,WAAW,EAAE,MAAM;IAG7B,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM;IAR3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B,SAAS,CAAC,KAAK,QAAe;IAE9B,SAAS,aACG,WAAW,EAAE,MAAM,EAC7B,MAAM,CAAC,EAAE,cAAc,EACvB,WAAW,GAAE,MAA8B,EACjC,MAAM,CAAC,EAAE,MAAM,YAAA;IAK3B,IAAI,eAAmE;IAEvE,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnC,SAAS,CAAC,kBAAkB,GAC1B,IAAI,MAAM,OAAO,CAAC,OAAO,CAAC,EAC1B,KAAK,MAAM,EACX,cAAc,MAAM,IAAI,KACvB,OAAO,CAAC,OAAO,CAAC,CAWjB;IAEF;;;;;OAKG;IACH,SAAS,CAAC,WAAW,GACnB,OAAO,KAAK,EACZ,cAAc,KAAK,CAAC,eAAe,CAAC,mBAyCpC;IAEF;;;OAGG;IACH,SAAS,CAAC,YAAY,GAAU,OAAO,KAAK,mBAmB1C;CACH;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
@@ -0,0 +1,90 @@
1
+ import { Mutex } from '@rosen-bridge/semaphore';
2
+ import { AbstractScanner } from './scanner';
3
+ const DEFAULT_MAX_TRY_BLOCK = 10;
4
+ class WebSocketScanner extends AbstractScanner {
5
+ scannerName;
6
+ suffix;
7
+ maxTryBlock;
8
+ mutex = new Mutex();
9
+ constructor(scannerName, logger, maxTryBlock = DEFAULT_MAX_TRY_BLOCK, suffix) {
10
+ super(logger);
11
+ this.scannerName = scannerName;
12
+ this.suffix = suffix;
13
+ this.maxTryBlock = maxTryBlock;
14
+ }
15
+ name = () => this.scannerName + (this.suffix ? `-${this.suffix}` : '');
16
+ tryRunningFunction = async (fn, msg, releaseMutex) => {
17
+ for (let tryRound = 1; tryRound <= this.maxTryBlock; tryRound++) {
18
+ if (await fn())
19
+ return true;
20
+ }
21
+ releaseMutex();
22
+ this.logger.error(`${msg} can not be proceed in ${this.maxTryBlock} try. scanner restarted automatically`);
23
+ await this.stop();
24
+ await this.start();
25
+ return false;
26
+ };
27
+ /**
28
+ * Handle new block arrived.
29
+ * save block and its transactions.
30
+ * @param block
31
+ * @param transactions
32
+ */
33
+ stepForward = async (block, transactions) => {
34
+ const release = await this.mutex.acquire();
35
+ await this.tryRunningFunction(async () => {
36
+ try {
37
+ await this.forkBlock(block.height);
38
+ const lastSavedBlock = await this.action.getLastSavedBlock();
39
+ if (lastSavedBlock && block.parentHash !== lastSavedBlock.hash) {
40
+ this.logger.error('It seems saved block is not valid in scanner.');
41
+ return false;
42
+ }
43
+ else {
44
+ await this.verifyExtractorsInitialization({
45
+ height: block.height - 1,
46
+ hash: block.parentHash,
47
+ });
48
+ const res = await this.processBlockTransactions(block, transactions);
49
+ if (res === false) {
50
+ this.logger.error(`Can not process block at height ${block.height}`);
51
+ }
52
+ else {
53
+ return true;
54
+ }
55
+ }
56
+ }
57
+ catch (e) {
58
+ this.logger.warn(`unknown error occurred ${e}`);
59
+ if (e instanceof Error && e.stack) {
60
+ this.logger.warn(e.stack);
61
+ }
62
+ }
63
+ return false;
64
+ }, `Block at height ${block.height}`, release);
65
+ release();
66
+ };
67
+ /**
68
+ * Handle forking a block
69
+ * @param block
70
+ */
71
+ stepBackward = async (block) => {
72
+ const release = await this.mutex.acquire();
73
+ await this.tryRunningFunction(async () => {
74
+ try {
75
+ await this.forkBlock(block.height + 1);
76
+ return true;
77
+ }
78
+ catch (e) {
79
+ this.logger.error(`unknown error occurred ${e}`);
80
+ if (e instanceof Error && e.stack) {
81
+ this.logger.warn(e.stack);
82
+ }
83
+ }
84
+ return false;
85
+ }, `Forking block at height ${block.height}`, release);
86
+ release();
87
+ };
88
+ }
89
+ export { WebSocketScanner };
90
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViU29ja2V0U2Nhbm5lci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9zY2FubmVyL2Fic3RyYWN0L3dlYlNvY2tldFNjYW5uZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRWhELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFNUMsTUFBTSxxQkFBcUIsR0FBRyxFQUFFLENBQUM7QUFFakMsTUFBZSxnQkFFYixTQUFRLGVBQWdDO0lBTTVCO0lBR0E7SUFSSCxXQUFXLENBQVM7SUFFbkIsS0FBSyxHQUFHLElBQUksS0FBSyxFQUFFLENBQUM7SUFFOUIsWUFDWSxXQUFtQixFQUM3QixNQUF1QixFQUN2QixjQUFzQixxQkFBcUIsRUFDakMsTUFBZTtRQUV6QixLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7UUFMSixnQkFBVyxHQUFYLFdBQVcsQ0FBUTtRQUduQixXQUFNLEdBQU4sTUFBTSxDQUFTO1FBR3pCLElBQUksQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDO0lBQ2pDLENBQUM7SUFDRCxJQUFJLEdBQUcsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUs3RCxrQkFBa0IsR0FBRyxLQUFLLEVBQ2xDLEVBQTBCLEVBQzFCLEdBQVcsRUFDWCxZQUF3QixFQUNOLEVBQUU7UUFDcEIsS0FBSyxJQUFJLFFBQVEsR0FBRyxDQUFDLEVBQUUsUUFBUSxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsUUFBUSxFQUFFLEVBQUUsQ0FBQztZQUNoRSxJQUFJLE1BQU0sRUFBRSxFQUFFO2dCQUFFLE9BQU8sSUFBSSxDQUFDO1FBQzlCLENBQUM7UUFDRCxZQUFZ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SUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7b0JBQ2xDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDNUIsQ0FBQztZQUNILENBQUM7WUFDRCxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUMsRUFDRCwyQkFBMkIsS0FBSyxDQUFDLE1BQU0sRUFBRSxFQUN6QyxPQUFPLENBQ1IsQ0FBQztRQUNGLE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQyxDQUFDO0NBQ0g7QUFFRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFic3RyYWN0TG9nZ2VyIH0gZnJvbSAnQHJvc2VuLWJyaWRnZS9hYnN0cmFjdC1sb2dnZXInO1xuaW1wb3J0IHsgQmxvY2sgfSBmcm9tICdAcm9zZW4tYnJpZGdlL3NjYW5uZXItaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBNdXRleCB9IGZyb20gJ0Byb3Nlbi1icmlkZ2Uvc2VtYXBob3JlJztcblxuaW1wb3J0IHsgQWJzdHJhY3RTY2FubmVyIH0gZnJvbSAnLi9zY2FubmVyJztcblxuY29uc3QgREVGQVVMVF9NQVhfVFJZX0JMT0NLID0gMTA7XG5cbmFic3RyYWN0IGNsYXNzIFdlYlNvY2tldFNjYW5uZXI8XG4gIFRyYW5zYWN0aW9uVHlwZSxcbj4gZXh0ZW5kcyBBYnN0cmFjdFNjYW5uZXI8VHJhbnNhY3Rpb25UeXBlPiB7XG4gIHJlYWRvbmx5IG1heFRyeUJsb2NrOiBudW1iZXI7XG5cbiAgcHJvdGVjdGVkIG11dGV4ID0gbmV3IE11dGV4KCk7XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCBzY2FubmVyTmFtZTogc3RyaW5nLFxuICAgIGxvZ2dlcj86IEFic3RyYWN0TG9nZ2VyLFxuICAgIG1heFRyeUJsb2NrOiBudW1iZXIgPSBERUZBVUxUX01BWF9UUllfQkxPQ0ssXG4gICAgcHJvdGVjdGVkIHN1ZmZpeD86IHN0cmluZyxcbiAgKSB7XG4gICAgc3VwZXIobG9nZ2VyKTtcbiAgICB0aGlzLm1heFRyeUJsb2NrID0gbWF4VHJ5QmxvY2s7XG4gIH1cbiAgbmFtZSA9ICgpID0+IHRoaXMuc2Nhbm5lck5hbWUgKyAodGhpcy5zdWZmaXggPyBgLSR7dGhpcy5zdWZmaXh9YCA6ICcnKTtcblxuICBhYnN0cmFjdCBzdGFydDogKCkgPT4gUHJvbWlzZTx2b2lkPjtcbiAgYWJzdHJhY3Qgc3RvcDogKCkgPT4gUHJvbWlzZTx2b2lkPjtcblxuICBwcm90ZWN0ZWQgdHJ5UnVubmluZ0Z1bmN0aW9uID0gYXN5bmMgKFxuICAgIGZuOiAoKSA9PiBQcm9taXNlPGJvb2xlYW4+LFxuICAgIG1zZzogc3RyaW5nLFxuICAgIHJlbGVhc2VNdXRleDogKCkgPT4gdm9pZCxcbiAgKTogUHJvbWlzZTxib29sZWFuPiA9PiB7XG4gICAgZm9yIChsZXQgdHJ5Um91bmQgPSAxOyB0cnlSb3VuZCA8PSB0aGlzLm1heFRyeUJsb2NrOyB0cnlSb3VuZCsrKSB7XG4gICAgICBpZiAoYXdhaXQgZm4oKSkgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJlbGVhc2VNdXRleCgpO1xuICAgIHRoaXMubG9nZ2VyLmVycm9yKFxuICAgICAgYCR7bXNnfSBjYW4gbm90IGJlIHByb2NlZWQgaW4gJHt0aGlzLm1heFRyeUJsb2NrfSB0cnkuIHNjYW5uZXIgcmVzdGFydGVkIGF1dG9tYXRpY2FsbHlgLFxuICAgICk7XG4gICAgYXdhaXQgdGhpcy5zdG9wKCk7XG4gICAgYXdhaXQgdGhpcy5zdGFydCgpO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcblxuICAvKipcbiAgICogSGFuZGxlIG5ldyBibG9jayBhcnJpdmVkLlxuICAgKiBzYXZlIGJsb2NrIGFuZCBpdHMgdHJhbnNhY3Rpb25zLlxuICAgKiBAcGFyYW0gYmxvY2tcbiAgICogQHBhcmFtIHRyYW5zYWN0aW9uc1xuICAgKi9cbiAgcHJvdGVjdGVkIHN0ZXBGb3J3YXJkID0gYXN5bmMgKFxuICAgIGJsb2NrOiBCbG9jayxcbiAgICB0cmFuc2FjdGlvbnM6IEFycmF5PFRyYW5zYWN0aW9uVHlwZT4sXG4gICkgPT4ge1xuICAgIGNvbnN0IHJlbGVhc2UgPSBhd2FpdCB0aGlzLm11dGV4LmFjcXVpcmUoKTtcbiAgICBhd2FpdCB0aGlzLnRyeVJ1bm5pbmdGdW5jdGlvbihcbiAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCB0aGlzLmZvcmtCbG9jayhibG9jay5oZWlnaHQpO1xuXG4gICAgICAgICAgY29uc3QgbGFzdFNhdmVkQmxvY2sgPSBhd2FpdCB0aGlzLmFjdGlvbi5nZXRMYXN0U2F2ZWRCbG9jaygpO1xuICAgICAgICAgIGlmIChsYXN0U2F2ZWRCbG9jayAmJiBibG9jay5wYXJlbnRIYXNoICE9PSBsYXN0U2F2ZWRCbG9jay5oYXNoKSB7XG4gICAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcignSXQgc2VlbXMgc2F2ZWQgYmxvY2sgaXMgbm90IHZhbGlkIGluIHNjYW5uZXIuJyk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMudmVyaWZ5RXh0cmFjdG9yc0luaXRpYWxpemF0aW9uKHtcbiAgICAgICAgICAgICAgaGVpZ2h0OiBibG9jay5oZWlnaHQgLSAxLFxuICAgICAgICAgICAgICBoYXNoOiBibG9jay5wYXJlbnRIYXNoLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLnByb2Nlc3NCbG9ja1RyYW5zYWN0aW9ucyhcbiAgICAgICAgICAgICAgYmxvY2ssXG4gICAgICAgICAgICAgIHRyYW5zYWN0aW9ucyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAocmVzID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcihcbiAgICAgICAgICAgICAgICBgQ2FuIG5vdCBwcm9jZXNzIGJsb2NrIGF0IGhlaWdodCAke2Jsb2NrLmhlaWdodH1gLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgdGhpcy5sb2dnZXIud2FybihgdW5rbm93biBlcnJvciBvY2N1cnJlZCAke2V9YCk7XG4gICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBFcnJvciAmJiBlLnN0YWNrKSB7XG4gICAgICAgICAgICB0aGlzLmxvZ2dlci53YXJuKGUuc3RhY2spO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9LFxuICAgICAgYEJsb2NrIGF0IGhlaWdodCAke2Jsb2NrLmhlaWdodH1gLFxuICAgICAgcmVsZWFzZSxcbiAgICApO1xuICAgIHJlbGVhc2UoKTtcbiAgfTtcblxuICAvKipcbiAgICogSGFuZGxlIGZvcmtpbmcgYSBibG9ja1xuICAgKiBAcGFyYW0gYmxvY2tcbiAgICovXG4gIHByb3RlY3RlZCBzdGVwQmFja3dhcmQgPSBhc3luYyAoYmxvY2s6IEJsb2NrKSA9PiB7XG4gICAgY29uc3QgcmVsZWFzZSA9IGF3YWl0IHRoaXMubXV0ZXguYWNxdWlyZSgpO1xuICAgIGF3YWl0IHRoaXMudHJ5UnVubmluZ0Z1bmN0aW9uKFxuICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IHRoaXMuZm9ya0Jsb2NrKGJsb2NrLmhlaWdodCArIDEpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoYHVua25vd24gZXJyb3Igb2NjdXJyZWQgJHtlfWApO1xuICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgRXJyb3IgJiYgZS5zdGFjaykge1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIud2FybihlLnN0YWNrKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSxcbiAgICAgIGBGb3JraW5nIGJsb2NrIGF0IGhlaWdodCAke2Jsb2NrLmhlaWdodH1gLFxuICAgICAgcmVsZWFzZSxcbiAgICApO1xuICAgIHJlbGVhc2UoKTtcbiAgfTtcbn1cblxuZXhwb3J0IHsgV2ViU29ja2V0U2Nhbm5lciB9O1xuIl19
@@ -0,0 +1,83 @@
1
+ import { AbstractLogger } from '@rosen-bridge/abstract-logger';
2
+ import { DataSource, DeleteResult, Repository } from '@rosen-bridge/extended-typeorm';
3
+ import { Block } from '@rosen-bridge/scanner-interfaces';
4
+ import { BlockEntity } from '../entities/blockEntity';
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,cAAc,EAAe,MAAM,+BAA+B,CAAC;AAC5E,OAAO,EACL,UAAU,EACV,YAAY,EAEZ,UAAU,EAEX,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,kCAAkC,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAuB,MAAM,yBAAyB,CAAC;AAC3E,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,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAW5D;IAEF;;;;OAIG;IACH,kBAAkB,GAChB,MAAM,MAAM,EACZ,OAAO,MAAM,KACZ,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAO5B;IAEF;;;OAGG;IACH,kBAAkB,QAAa,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAW7D;IAEF;;;;;OAKG;IACH,gBAAgB,GACd,QAAQ,MAAM,EACd,SAAQ,MAAgB,KACvB,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAWjC;IAEF;;;;OAIG;IACH,gBAAgB,GAAU,MAAM,MAAM,EAAE,SAAQ,MAAgB,iCAM9D;IAEF;;;;OAIG;IACH,sBAAsB,GAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,YAAY,CAAC,CAMpE;IAEF;;;OAGG;IACH,SAAS,GAAU,OAAO,KAAK,KAAG,OAAO,CAAC,WAAW,GAAG,OAAO,CAAC,CA0C9D;IAEF;;;OAGG;IACH,iBAAiB,GACf,QAAQ,MAAM,EACd,WAAW,MAAM,EACjB,cAAc,MAAM,EAAE,KACrB,OAAO,CAAC,OAAO,CAAC,CAqCjB;IAEF;;;OAGG;IACH,iBAAiB,GACf,QAAQ,MAAM,EACd,YAAY,MAAM,EAClB,cAAc,MAAM,EAAE,KACrB,OAAO,CAAC,OAAO,CAAC,CAsCjB;IAEF;;;;;OAKG;IACH,6BAA6B,GAC3B,aAAa,MAAM,EACnB,QAAQ,MAAM,EACd,WAAW,MAAM;;;;;+BAgBjB;IAEF;;;;OAIG;IACH,mBAAmB,GACjB,cAAc,MAAM,EAAE,KACrB,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAKjC;CACH"}