@rosen-bridge/abstract-extractor 2.1.2 → 3.0.0-8f3c7016
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.
- package/CHANGELOG.md +9 -0
- package/dist/abstractExtractor.d.ts +24 -12
- package/dist/abstractExtractor.d.ts.map +1 -1
- package/dist/abstractExtractor.js +1 -1
- package/dist/constants.d.ts +1 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +2 -1
- package/dist/ergo/database/actions/abstractErgoAction.d.ts +83 -0
- package/dist/ergo/database/actions/abstractErgoAction.d.ts.map +1 -0
- package/dist/ergo/database/actions/abstractErgoAction.js +167 -0
- package/dist/ergo/database/actions/abstractErgoBoxAction.d.ts +31 -0
- package/dist/ergo/database/actions/abstractErgoBoxAction.d.ts.map +1 -0
- package/dist/ergo/database/actions/abstractErgoBoxAction.js +70 -0
- package/dist/ergo/database/entities/abstractErgoBoxEntity.d.ts +18 -0
- package/dist/ergo/database/entities/abstractErgoBoxEntity.d.ts.map +1 -0
- package/dist/ergo/database/entities/abstractErgoBoxEntity.js +36 -0
- package/dist/ergo/database/entities/abstractErgoEntity.d.ts +26 -0
- package/dist/ergo/database/entities/abstractErgoEntity.d.ts.map +1 -0
- package/dist/ergo/database/entities/abstractErgoEntity.js +64 -0
- package/dist/ergo/database/index.d.ts +5 -0
- package/dist/ergo/database/index.d.ts.map +1 -0
- package/dist/ergo/database/index.js +5 -0
- package/dist/ergo/extractors/abstractErgoBoxExtractor.d.ts +67 -0
- package/dist/ergo/extractors/abstractErgoBoxExtractor.d.ts.map +1 -0
- package/dist/ergo/extractors/abstractErgoBoxExtractor.js +106 -0
- package/dist/ergo/extractors/abstractErgoExtractor.d.ts +53 -0
- package/dist/ergo/extractors/abstractErgoExtractor.d.ts.map +1 -0
- package/dist/ergo/extractors/abstractErgoExtractor.js +92 -0
- package/dist/ergo/extractors/abstractErgoTxExtractor.d.ts +56 -0
- package/dist/ergo/extractors/abstractErgoTxExtractor.d.ts.map +1 -0
- package/dist/ergo/extractors/abstractErgoTxExtractor.js +81 -0
- package/dist/ergo/extractors/index.d.ts +4 -0
- package/dist/ergo/extractors/index.d.ts.map +1 -0
- package/dist/ergo/extractors/index.js +4 -0
- package/dist/ergo/index.d.ts +5 -7
- package/dist/ergo/index.d.ts.map +1 -1
- package/dist/ergo/index.js +6 -8
- package/dist/ergo/initializers/ergoBoxInitializer.d.ts +36 -0
- package/dist/ergo/initializers/ergoBoxInitializer.d.ts.map +1 -0
- package/dist/ergo/initializers/ergoBoxInitializer.js +80 -0
- package/dist/ergo/initializers/ergoInitializer.d.ts +39 -0
- package/dist/ergo/initializers/ergoInitializer.d.ts.map +1 -0
- package/dist/ergo/initializers/ergoInitializer.js +80 -0
- package/dist/ergo/initializers/index.d.ts +4 -0
- package/dist/ergo/initializers/index.d.ts.map +1 -0
- package/dist/ergo/initializers/index.js +4 -0
- package/dist/ergo/initializers/strategies/constants.d.ts +3 -0
- package/dist/ergo/initializers/strategies/constants.d.ts.map +1 -0
- package/dist/ergo/initializers/strategies/constants.js +3 -0
- package/dist/ergo/initializers/strategies/explorerInitializationStrategy.d.ts +59 -0
- package/dist/ergo/initializers/strategies/explorerInitializationStrategy.d.ts.map +1 -0
- package/dist/ergo/initializers/strategies/explorerInitializationStrategy.js +141 -0
- package/dist/ergo/initializers/strategies/index.d.ts +4 -0
- package/dist/ergo/initializers/strategies/index.d.ts.map +1 -0
- package/dist/ergo/initializers/strategies/index.js +4 -0
- package/dist/ergo/initializers/strategies/nodeInitializationStrategy.d.ts +29 -0
- package/dist/ergo/initializers/strategies/nodeInitializationStrategy.d.ts.map +1 -0
- package/dist/ergo/initializers/strategies/nodeInitializationStrategy.js +66 -0
- package/dist/ergo/initializers/strategies/workerManager.d.ts +79 -0
- package/dist/ergo/initializers/strategies/workerManager.d.ts.map +1 -0
- package/dist/ergo/initializers/strategies/workerManager.js +183 -0
- package/dist/ergo/interfaces.d.ts +31 -17
- package/dist/ergo/interfaces.d.ts.map +1 -1
- package/dist/ergo/interfaces.js +1 -1
- package/dist/ergo/networks/explorerNetwork.d.ts +52 -0
- package/dist/ergo/networks/explorerNetwork.d.ts.map +1 -0
- package/dist/ergo/networks/explorerNetwork.js +127 -0
- package/dist/ergo/networks/index.d.ts +3 -0
- package/dist/ergo/networks/index.d.ts.map +1 -0
- package/dist/ergo/networks/index.js +3 -0
- package/dist/ergo/networks/nodeNetwork.d.ts +28 -0
- package/dist/ergo/networks/nodeNetwork.d.ts.map +1 -0
- package/dist/ergo/networks/nodeNetwork.js +59 -0
- package/dist/ergo/utils.d.ts +15 -0
- package/dist/ergo/utils.d.ts.map +1 -1
- package/dist/ergo/utils.js +34 -1
- package/package.json +3 -1
- package/dist/ergo/abstractErgoExtractor.d.ts +0 -80
- package/dist/ergo/abstractErgoExtractor.d.ts.map +0 -1
- package/dist/ergo/abstractErgoExtractor.js +0 -142
- package/dist/ergo/abstractErgoExtractorAction.d.ts +0 -89
- package/dist/ergo/abstractErgoExtractorAction.d.ts.map +0 -1
- package/dist/ergo/abstractErgoExtractorAction.js +0 -219
- package/dist/ergo/abstractErgoExtractorEntity.d.ts +0 -11
- package/dist/ergo/abstractErgoExtractorEntity.d.ts.map +0 -1
- package/dist/ergo/abstractErgoExtractorEntity.js +0 -57
- package/dist/ergo/initializable/abstractInitializable.d.ts +0 -48
- package/dist/ergo/initializable/abstractInitializable.d.ts.map +0 -1
- package/dist/ergo/initializable/abstractInitializable.js +0 -162
- package/dist/ergo/initializable/abstractInitializableAction.d.ts +0 -14
- package/dist/ergo/initializable/abstractInitializableAction.d.ts.map +0 -1
- package/dist/ergo/initializable/abstractInitializableAction.js +0 -16
- package/dist/ergo/initializable/index.d.ts +0 -3
- package/dist/ergo/initializable/index.d.ts.map +0 -1
- package/dist/ergo/initializable/index.js +0 -3
- package/dist/ergo/network/abstractNetwork.d.ts +0 -26
- package/dist/ergo/network/abstractNetwork.d.ts.map +0 -1
- package/dist/ergo/network/abstractNetwork.js +0 -3
- package/dist/ergo/network/explorerNetwork.d.ts +0 -74
- package/dist/ergo/network/explorerNetwork.d.ts.map +0 -1
- package/dist/ergo/network/explorerNetwork.js +0 -185
- package/dist/ergo/network/nodeNetwork.d.ts +0 -60
- package/dist/ergo/network/nodeNetwork.d.ts.map +0 -1
- package/dist/ergo/network/nodeNetwork.js +0 -131
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { DummyLogger } from '@rosen-bridge/abstract-logger';
|
|
2
|
+
import { BlockInfo } from '@rosen-bridge/scanner-interfaces';
|
|
3
|
+
import { ExtendedTransaction } from '../../interfaces';
|
|
4
|
+
export declare class NodeInitializationStrategy {
|
|
5
|
+
private address;
|
|
6
|
+
private maxParallelRequests;
|
|
7
|
+
private processTransactionBatch;
|
|
8
|
+
private logger;
|
|
9
|
+
private network;
|
|
10
|
+
constructor(url: string, address: string, maxParallelRequests: number, processTransactionBatch: (txs: ExtendedTransaction[]) => Promise<void>, logger?: DummyLogger);
|
|
11
|
+
/**
|
|
12
|
+
* Get the total tx count from Node network
|
|
13
|
+
* @returns total tx count of the address
|
|
14
|
+
*/
|
|
15
|
+
private getTotalTxCount;
|
|
16
|
+
/**
|
|
17
|
+
* Processing node transactions with offset and limit
|
|
18
|
+
* @param offset
|
|
19
|
+
* @param limit
|
|
20
|
+
* @param initialHeight
|
|
21
|
+
*/
|
|
22
|
+
private processWithOffsetLimit;
|
|
23
|
+
/**
|
|
24
|
+
* Initialize extractor using Node network
|
|
25
|
+
* @param initialBlock
|
|
26
|
+
*/
|
|
27
|
+
initialize: (initialBlock: BlockInfo) => Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=nodeInitializationStrategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nodeInitializationStrategy.d.ts","sourceRoot":"","sources":["../../../../lib/ergo/initializers/strategies/nodeInitializationStrategy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAG7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAKvD,qBAAa,0BAA0B;IAKnC,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,uBAAuB;IAG/B,OAAO,CAAC,MAAM;IAThB,OAAO,CAAC,OAAO,CAAc;gBAG3B,GAAG,EAAE,MAAM,EACH,OAAO,EAAE,MAAM,EACf,mBAAmB,EAAE,MAAM,EAC3B,uBAAuB,EAAE,CAC/B,GAAG,EAAE,mBAAmB,EAAE,KACvB,OAAO,CAAC,IAAI,CAAC,EACV,MAAM,cAAoB;IAKpC;;;OAGG;IACH,OAAO,CAAC,eAAe,CAOrB;IAEF;;;;;OAKG;IACH,OAAO,CAAC,sBAAsB,CAuB5B;IAEF;;;OAGG;IACH,UAAU,GAAU,cAAc,SAAS,mBAmBzC;CACH"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import PQueue from 'p-queue';
|
|
2
|
+
import { DummyLogger } from '@rosen-bridge/abstract-logger';
|
|
3
|
+
import { API_LIMIT } from '../../../constants';
|
|
4
|
+
import { NodeNetwork } from '../../networks/nodeNetwork';
|
|
5
|
+
import { delay, requestWithRetrial } from '../../utils';
|
|
6
|
+
import { DELAY_BETWEEN_INIT_REQUESTS } from './constants';
|
|
7
|
+
export class NodeInitializationStrategy {
|
|
8
|
+
address;
|
|
9
|
+
maxParallelRequests;
|
|
10
|
+
processTransactionBatch;
|
|
11
|
+
logger;
|
|
12
|
+
network;
|
|
13
|
+
constructor(url, address, maxParallelRequests, processTransactionBatch, logger = new DummyLogger()) {
|
|
14
|
+
this.address = address;
|
|
15
|
+
this.maxParallelRequests = maxParallelRequests;
|
|
16
|
+
this.processTransactionBatch = processTransactionBatch;
|
|
17
|
+
this.logger = logger;
|
|
18
|
+
this.network = new NodeNetwork(url);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get the total tx count from Node network
|
|
22
|
+
* @returns total tx count of the address
|
|
23
|
+
*/
|
|
24
|
+
getTotalTxCount = async () => {
|
|
25
|
+
const response = await this.network.getAddressTransactionsWithOffsetLimit(this.address, 0, 0);
|
|
26
|
+
return response.total;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Processing node transactions with offset and limit
|
|
30
|
+
* @param offset
|
|
31
|
+
* @param limit
|
|
32
|
+
* @param initialHeight
|
|
33
|
+
*/
|
|
34
|
+
processWithOffsetLimit = async (offset, limit, initialHeight) => {
|
|
35
|
+
this.logger.debug(`Requesting node getTxsByAddress with offset ${offset}`);
|
|
36
|
+
const response = await requestWithRetrial(() => this.network.getAddressTransactionsWithOffsetLimit(this.address, offset, limit), this.logger);
|
|
37
|
+
const txs = response.items.filter((tx) => tx.inclusionHeight <= initialHeight);
|
|
38
|
+
this.logger.debug(`Found ${txs.length} new transactions below the initial height with offset ${offset}, total is ${response.total}`);
|
|
39
|
+
if (txs.length > 0)
|
|
40
|
+
await this.processTransactionBatch(txs);
|
|
41
|
+
this.logger.debug(`Processing completed for request with offset ${offset}`);
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Initialize extractor using Node network
|
|
45
|
+
* @param initialBlock
|
|
46
|
+
*/
|
|
47
|
+
initialize = async (initialBlock) => {
|
|
48
|
+
try {
|
|
49
|
+
let offset = 0;
|
|
50
|
+
const total = await this.getTotalTxCount();
|
|
51
|
+
const promiseQueue = new PQueue({
|
|
52
|
+
concurrency: this.maxParallelRequests,
|
|
53
|
+
});
|
|
54
|
+
while (offset < total) {
|
|
55
|
+
await delay(DELAY_BETWEEN_INIT_REQUESTS);
|
|
56
|
+
((offset) => promiseQueue.add(() => this.processWithOffsetLimit(offset, API_LIMIT, initialBlock.height)))(offset);
|
|
57
|
+
offset += API_LIMIT;
|
|
58
|
+
}
|
|
59
|
+
await promiseQueue.onIdle();
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
throw new Error(`Error initializing extractor by node: ${error}`);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZUluaXRpYWxpemF0aW9uU3RyYXRlZ3kuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9saWIvZXJnby9pbml0aWFsaXplcnMvc3RyYXRlZ2llcy9ub2RlSW5pdGlhbGl6YXRpb25TdHJhdGVneS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLE1BQU0sTUFBTSxTQUFTLENBQUM7QUFFN0IsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRzVELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUUvQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDekQsT0FBTyxFQUFFLEtBQUssRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN4RCxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFMUQsTUFBTSxPQUFPLDBCQUEwQjtJQUszQjtJQUNBO0lBQ0E7SUFHQTtJQVRGLE9BQU8sQ0FBYztJQUU3QixZQUNFLEdBQVcsRUFDSCxPQUFlLEVBQ2YsbUJBQTJCLEVBQzNCLHVCQUVVLEVBQ1YsU0FBUyxJQUFJLFdBQVcsRUFBRTtRQUwxQixZQUFPLEdBQVAsT0FBTyxDQUFRO1FBQ2Ysd0JBQW1CLEdBQW5CLG1CQUFtQixDQUFRO1FBQzNCLDRCQUF1QixHQUF2Qix1QkFBdUIsQ0FFYjtRQUNWLFdBQU0sR0FBTixNQUFNLENBQW9CO1FBRWxDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDdEMsQ0FBQztJQUVEOzs7T0FHRztJQUNLLGVBQWUsR0FBRyxLQUFLLElBQUksRUFBRTtRQUNuQyxNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMscUNBQXFDLENBQ3ZFLElBQUksQ0FBQyxPQUFPLEVBQ1osQ0FBQyxFQUNELENBQUMsQ0FDRixDQUFDO1FBQ0YsT0FBTyxRQUFRLENBQUMsS0FBSyxDQUFDO0lBQ3hCLENBQUMsQ0FBQztJQUVGOzs7OztPQUtHO0lBQ0ssc0JBQXNCLEdBQUcsS0FBSyxFQUNwQyxNQUFjLEVBQ2QsS0FBYSxFQUNiLGFBQXFCLEVBQ3JCLEVBQUU7UUFDRixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQywrQ0FBK0MsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUMzRSxNQUFNLFFBQVEsR0FBRyxNQUFNLGtCQUFrQixDQUN2QyxHQUFHLEVBQUUsQ0FDSCxJQUFJLENBQUMsT0FBTyxDQUFDLHFDQUFxQyxDQUNoRCxJQUFJLENBQUMsT0FBTyxFQUNaLE1BQU0sRUFDTixLQUFLLENBQ04sRUFDSCxJQUFJLENBQUMsTUFBTSxDQUNaLENBQUM7UUFDRixNQUFNLEdBQUcsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FDL0IsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxlQUFlLElBQUksYUFBYSxDQUM1QyxDQUFDO1FBQ0YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQ2YsU0FBUyxHQUFHLENBQUMsTUFBTSwwREFBMEQsTUFBTSxjQUFjLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FDbEgsQ0FBQztRQUNGLElBQUksR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDO1lBQUUsTUFBTSxJQUFJLENBQUMsdUJBQXVCLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDNUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsZ0RBQWdELE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDOUUsQ0FBQyxDQUFDO0lBRUY7OztPQUdHO0lBQ0gsVUFBVSxHQUFHLEtBQUssRUFBRSxZQUF1QixFQUFFLEVBQUU7UUFDN0MsSUFBSSxDQUFDO1lBQ0gsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO1lBQ2YsTUFBTSxLQUFLLEdBQUcsTUFBTSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDM0MsTUFBTSxZQUFZLEdBQUcsSUFBSSxNQUFNLENBQUM7Z0JBQzlCLFdBQVcsRUFBRSxJQUFJLENBQUMsbUJBQW1CO2FBQ3RDLENBQUMsQ0FBQztZQUNILE9BQU8sTUFBTSxHQUFHLEtBQUssRUFBRSxDQUFDO2dCQUN0QixNQUFNLEtBQUssQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO2dCQUN6QyxDQUFDLENBQUMsTUFBYyxFQUFFLEVBQUUsQ0FDbEIsWUFBWSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FDcEIsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUNwRSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQ2IsTUFBTSxJQUFJLFNBQVMsQ0FBQztZQUN0QixDQUFDO1lBQ0QsTUFBTSxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDOUIsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixNQUFNLElBQUksS0FBSyxDQUFDLHlDQUF5QyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3BFLENBQUM7SUFDSCxDQUFDLENBQUM7Q0FDSCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQUXVldWUgZnJvbSAncC1xdWV1ZSc7XG5cbmltcG9ydCB7IER1bW15TG9nZ2VyIH0gZnJvbSAnQHJvc2VuLWJyaWRnZS9hYnN0cmFjdC1sb2dnZXInO1xuaW1wb3J0IHsgQmxvY2tJbmZvIH0gZnJvbSAnQHJvc2VuLWJyaWRnZS9zY2FubmVyLWludGVyZmFjZXMnO1xuXG5pbXBvcnQgeyBBUElfTElNSVQgfSBmcm9tICcuLi8uLi8uLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgRXh0ZW5kZWRUcmFuc2FjdGlvbiB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgTm9kZU5ldHdvcmsgfSBmcm9tICcuLi8uLi9uZXR3b3Jrcy9ub2RlTmV0d29yayc7XG5pbXBvcnQgeyBkZWxheSwgcmVxdWVzdFdpdGhSZXRyaWFsIH0gZnJvbSAnLi4vLi4vdXRpbHMnO1xuaW1wb3J0IHsgREVMQVlfQkVUV0VFTl9JTklUX1JFUVVFU1RTIH0gZnJvbSAnLi9jb25zdGFudHMnO1xuXG5leHBvcnQgY2xhc3MgTm9kZUluaXRpYWxpemF0aW9uU3RyYXRlZ3kge1xuICBwcml2YXRlIG5ldHdvcms6IE5vZGVOZXR3b3JrO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHVybDogc3RyaW5nLFxuICAgIHByaXZhdGUgYWRkcmVzczogc3RyaW5nLFxuICAgIHByaXZhdGUgbWF4UGFyYWxsZWxSZXF1ZXN0czogbnVtYmVyLFxuICAgIHByaXZhdGUgcHJvY2Vzc1RyYW5zYWN0aW9uQmF0Y2g6IChcbiAgICAgIHR4czogRXh0ZW5kZWRUcmFuc2FjdGlvbltdLFxuICAgICkgPT4gUHJvbWlzZTx2b2lkPixcbiAgICBwcml2YXRlIGxvZ2dlciA9IG5ldyBEdW1teUxvZ2dlcigpLFxuICApIHtcbiAgICB0aGlzLm5ldHdvcmsgPSBuZXcgTm9kZU5ldHdvcmsodXJsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIHRvdGFsIHR4IGNvdW50IGZyb20gTm9kZSBuZXR3b3JrXG4gICAqIEByZXR1cm5zIHRvdGFsIHR4IGNvdW50IG9mIHRoZSBhZGRyZXNzXG4gICAqL1xuICBwcml2YXRlIGdldFRvdGFsVHhDb3VudCA9IGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMubmV0d29yay5nZXRBZGRyZXNzVHJhbnNhY3Rpb25zV2l0aE9mZnNldExpbWl0KFxuICAgICAgdGhpcy5hZGRyZXNzLFxuICAgICAgMCxcbiAgICAgIDAsXG4gICAgKTtcbiAgICByZXR1cm4gcmVzcG9uc2UudG90YWw7XG4gIH07XG5cbiAgLyoqXG4gICAqIFByb2Nlc3Npbmcgbm9kZSB0cmFuc2FjdGlvbnMgd2l0aCBvZmZzZXQgYW5kIGxpbWl0XG4gICAqIEBwYXJhbSBvZmZzZXRcbiAgICogQHBhcmFtIGxpbWl0XG4gICAqIEBwYXJhbSBpbml0aWFsSGVpZ2h0XG4gICAqL1xuICBwcml2YXRlIHByb2Nlc3NXaXRoT2Zmc2V0TGltaXQgPSBhc3luYyAoXG4gICAgb2Zmc2V0OiBudW1iZXIsXG4gICAgbGltaXQ6IG51bWJlcixcbiAgICBpbml0aWFsSGVpZ2h0OiBudW1iZXIsXG4gICkgPT4ge1xuICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBSZXF1ZXN0aW5nIG5vZGUgZ2V0VHhzQnlBZGRyZXNzIHdpdGggb2Zmc2V0ICR7b2Zmc2V0fWApO1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgcmVxdWVzdFdpdGhSZXRyaWFsKFxuICAgICAgKCkgPT5cbiAgICAgICAgdGhpcy5uZXR3b3JrLmdldEFkZHJlc3NUcmFuc2FjdGlvbnNXaXRoT2Zmc2V0TGltaXQoXG4gICAgICAgICAgdGhpcy5hZGRyZXNzLFxuICAgICAgICAgIG9mZnNldCxcbiAgICAgICAgICBsaW1pdCxcbiAgICAgICAgKSxcbiAgICAgIHRoaXMubG9nZ2VyLFxuICAgICk7XG4gICAgY29uc3QgdHhzID0gcmVzcG9uc2UuaXRlbXMuZmlsdGVyKFxuICAgICAgKHR4KSA9PiB0eC5pbmNsdXNpb25IZWlnaHQgPD0gaW5pdGlhbEhlaWdodCxcbiAgICApO1xuICAgIHRoaXMubG9nZ2VyLmRlYnVnKFxuICAgICAgYEZvdW5kICR7dHhzLmxlbmd0aH0gbmV3IHRyYW5zYWN0aW9ucyBiZWxvdyB0aGUgaW5pdGlhbCBoZWlnaHQgd2l0aCBvZmZzZXQgJHtvZmZzZXR9LCB0b3RhbCBpcyAke3Jlc3BvbnNlLnRvdGFsfWAsXG4gICAgKTtcbiAgICBpZiAodHhzLmxlbmd0aCA+IDApIGF3YWl0IHRoaXMucHJvY2Vzc1RyYW5zYWN0aW9uQmF0Y2godHhzKTtcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgUHJvY2Vzc2luZyBjb21wbGV0ZWQgZm9yIHJlcXVlc3Qgd2l0aCBvZmZzZXQgJHtvZmZzZXR9YCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemUgZXh0cmFjdG9yIHVzaW5nIE5vZGUgbmV0d29ya1xuICAgKiBAcGFyYW0gaW5pdGlhbEJsb2NrXG4gICAqL1xuICBpbml0aWFsaXplID0gYXN5bmMgKGluaXRpYWxCbG9jazogQmxvY2tJbmZvKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGxldCBvZmZzZXQgPSAwO1xuICAgICAgY29uc3QgdG90YWwgPSBhd2FpdCB0aGlzLmdldFRvdGFsVHhDb3VudCgpO1xuICAgICAgY29uc3QgcHJvbWlzZVF1ZXVlID0gbmV3IFBRdWV1ZSh7XG4gICAgICAgIGNvbmN1cnJlbmN5OiB0aGlzLm1heFBhcmFsbGVsUmVxdWVzdHMsXG4gICAgICB9KTtcbiAgICAgIHdoaWxlIChvZmZzZXQgPCB0b3RhbCkge1xuICAgICAgICBhd2FpdCBkZWxheShERUxBWV9CRVRXRUVOX0lOSVRfUkVRVUVTVFMpO1xuICAgICAgICAoKG9mZnNldDogbnVtYmVyKSA9PlxuICAgICAgICAgIHByb21pc2VRdWV1ZS5hZGQoKCkgPT5cbiAgICAgICAgICAgIHRoaXMucHJvY2Vzc1dpdGhPZmZzZXRMaW1pdChvZmZzZXQsIEFQSV9MSU1JVCwgaW5pdGlhbEJsb2NrLmhlaWdodCksXG4gICAgICAgICAgKSkob2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0ICs9IEFQSV9MSU1JVDtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHByb21pc2VRdWV1ZS5vbklkbGUoKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFcnJvciBpbml0aWFsaXppbmcgZXh0cmFjdG9yIGJ5IG5vZGU6ICR7ZXJyb3J9YCk7XG4gICAgfVxuICB9O1xufVxuIl19
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { DummyLogger } from '@rosen-bridge/abstract-logger';
|
|
2
|
+
import { RangeQuery } from '../../interfaces';
|
|
3
|
+
export declare class WorkerManager {
|
|
4
|
+
private workerCount;
|
|
5
|
+
private getRangeTxCount;
|
|
6
|
+
private logger;
|
|
7
|
+
private workersRangeList;
|
|
8
|
+
private mutex;
|
|
9
|
+
private initialSegmentSize;
|
|
10
|
+
private maxHeight?;
|
|
11
|
+
constructor(workerCount: number, getRangeTxCount: (start: number, end: number) => Promise<number>, logger?: DummyLogger);
|
|
12
|
+
/**
|
|
13
|
+
* Setup the worker manager to start working
|
|
14
|
+
* @param maxHeight
|
|
15
|
+
*/
|
|
16
|
+
setup: (maxHeight: number) => void;
|
|
17
|
+
/**
|
|
18
|
+
* Checks if the worker's search range is completed
|
|
19
|
+
* @param workerIndex
|
|
20
|
+
* @returns true if worker has an incomplete range to work on
|
|
21
|
+
*/
|
|
22
|
+
isWorkerActive: (workerIndex: number) => boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Register the worker for the first time
|
|
25
|
+
* splits the whole range equally between workers
|
|
26
|
+
* @param workerIndex
|
|
27
|
+
*/
|
|
28
|
+
registerWorker: (workerIndex: number) => Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Add a new range to the workers range list
|
|
31
|
+
* new range is a subset of all existing ranges
|
|
32
|
+
* @param workerIndex
|
|
33
|
+
* @param start
|
|
34
|
+
* @param end
|
|
35
|
+
*/
|
|
36
|
+
private addWorkerRange;
|
|
37
|
+
/**
|
|
38
|
+
* Limit the last range by adding a new range query to the workers range list
|
|
39
|
+
* the new range the first half of the last existing range
|
|
40
|
+
* @param workerIndex
|
|
41
|
+
*/
|
|
42
|
+
limitLastRange: (workerIndex: number) => Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Pop the last range query after being processed
|
|
45
|
+
* also update all older ranges and deduct the processed numbers
|
|
46
|
+
* @param workerIndex
|
|
47
|
+
*/
|
|
48
|
+
popLastRangeQuery: (workerIndex: number) => Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Find the biggest incomplete range list containing at least 2 ranges
|
|
51
|
+
* the range list must have at least two range so that it wont become empty
|
|
52
|
+
* after splitting the range between two workers
|
|
53
|
+
* @returns biggest incomplete range list index
|
|
54
|
+
*/
|
|
55
|
+
private getBiggestIncompleteRangeIndex;
|
|
56
|
+
/**
|
|
57
|
+
* Check all workers and reassign incomplete ranges to the idle ones
|
|
58
|
+
* do nothing if all workers are active
|
|
59
|
+
* do nothing if there is no incomplete range list
|
|
60
|
+
* split the biggest range list between the current worker and the idle worker
|
|
61
|
+
* @returns
|
|
62
|
+
*/
|
|
63
|
+
reassignIdleWorkers: () => Promise<number[]>;
|
|
64
|
+
/**
|
|
65
|
+
* Get the last (biggest) processable range from the worker's range list
|
|
66
|
+
*
|
|
67
|
+
* After the last range is processed, the older ones are updated and usually
|
|
68
|
+
* become smaller. Some of them might shrink below a certain threshold, which
|
|
69
|
+
* means they can now be processed too.
|
|
70
|
+
* This function finds the biggest range that is small enough to be processed,
|
|
71
|
+
* and removes all of its child ranges from the list.
|
|
72
|
+
* Returns the last range if none of them is processable.
|
|
73
|
+
* @param workerIndex
|
|
74
|
+
* @param rangeThreshold
|
|
75
|
+
* @returns range query
|
|
76
|
+
*/
|
|
77
|
+
getLastRange: (workerIndex: number, rangeThreshold: number) => Promise<RangeQuery>;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=workerManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workerManager.d.ts","sourceRoot":"","sources":["../../../../lib/ergo/initializers/strategies/workerManager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAE5D,OAAO,EAAa,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEzD,qBAAa,aAAa;IAOtB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,eAAe;IACvB,OAAO,CAAC,MAAM;IARhB,OAAO,CAAC,gBAAgB,CAAc;IACtC,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,SAAS,CAAC,CAAS;gBAGjB,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,EAChE,MAAM,cAAoB;IAGpC;;;OAGG;IACH,KAAK,GAAI,WAAW,MAAM,UAIxB;IAEF;;;;OAIG;IACH,cAAc,GAAI,aAAa,MAAM,KAAG,OAAO,CAE7C;IAEF;;;;OAIG;IACH,cAAc,GAAU,aAAa,MAAM,mBAYzC;IAEF;;;;;;OAMG;IACH,OAAO,CAAC,cAAc,CAapB;IAEF;;;;OAIG;IACH,cAAc,GAAU,aAAa,MAAM,mBAazC;IAEF;;;;OAIG;IACH,iBAAiB,GAAU,aAAa,MAAM,mBAU5C;IAEF;;;;;OAKG;IACH,OAAO,CAAC,8BAA8B,CAWpC;IAEF;;;;;;OAMG;IACH,mBAAmB,QAAa,OAAO,CAAC,MAAM,EAAE,CAAC,CA+C/C;IAEF;;;;;;;;;;;;OAYG;IACH,YAAY,GACV,aAAa,MAAM,EACnB,gBAAgB,MAAM,KACrB,OAAO,CAAC,UAAU,CAAC,CAkBpB;CACH"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { Mutex } from 'await-semaphore';
|
|
2
|
+
import { DummyLogger } from '@rosen-bridge/abstract-logger';
|
|
3
|
+
export class WorkerManager {
|
|
4
|
+
workerCount;
|
|
5
|
+
getRangeTxCount;
|
|
6
|
+
logger;
|
|
7
|
+
workersRangeList;
|
|
8
|
+
mutex = new Mutex();
|
|
9
|
+
initialSegmentSize;
|
|
10
|
+
maxHeight;
|
|
11
|
+
constructor(workerCount, getRangeTxCount, logger = new DummyLogger()) {
|
|
12
|
+
this.workerCount = workerCount;
|
|
13
|
+
this.getRangeTxCount = getRangeTxCount;
|
|
14
|
+
this.logger = logger;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Setup the worker manager to start working
|
|
18
|
+
* @param maxHeight
|
|
19
|
+
*/
|
|
20
|
+
setup = (maxHeight) => {
|
|
21
|
+
this.maxHeight = maxHeight;
|
|
22
|
+
this.workersRangeList = Array.from({ length: this.workerCount }, () => []);
|
|
23
|
+
this.initialSegmentSize = Math.ceil(this.maxHeight / this.workerCount);
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Checks if the worker's search range is completed
|
|
27
|
+
* @param workerIndex
|
|
28
|
+
* @returns true if worker has an incomplete range to work on
|
|
29
|
+
*/
|
|
30
|
+
isWorkerActive = (workerIndex) => {
|
|
31
|
+
return this.workersRangeList[workerIndex].length > 0;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Register the worker for the first time
|
|
35
|
+
* splits the whole range equally between workers
|
|
36
|
+
* @param workerIndex
|
|
37
|
+
*/
|
|
38
|
+
registerWorker = async (workerIndex) => {
|
|
39
|
+
if (!this.maxHeight)
|
|
40
|
+
throw Error('Please call setup before registering workers');
|
|
41
|
+
const start = workerIndex * this.initialSegmentSize;
|
|
42
|
+
const end = Math.min((workerIndex + 1) * this.initialSegmentSize - 1, this.maxHeight);
|
|
43
|
+
await this.addWorkerRange(workerIndex, start, end);
|
|
44
|
+
this.logger.debug(`Worker-${workerIndex} is initialized with range [${start}, ${end}]`);
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Add a new range to the workers range list
|
|
48
|
+
* new range is a subset of all existing ranges
|
|
49
|
+
* @param workerIndex
|
|
50
|
+
* @param start
|
|
51
|
+
* @param end
|
|
52
|
+
*/
|
|
53
|
+
addWorkerRange = async (workerIndex, start, end) => {
|
|
54
|
+
const count = await this.getRangeTxCount(start, end);
|
|
55
|
+
const release = await this.mutex.acquire();
|
|
56
|
+
this.workersRangeList[workerIndex].push({
|
|
57
|
+
start,
|
|
58
|
+
end,
|
|
59
|
+
count,
|
|
60
|
+
});
|
|
61
|
+
release();
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Limit the last range by adding a new range query to the workers range list
|
|
65
|
+
* the new range the first half of the last existing range
|
|
66
|
+
* @param workerIndex
|
|
67
|
+
*/
|
|
68
|
+
limitLastRange = async (workerIndex) => {
|
|
69
|
+
const lastRangeQuery = this.workersRangeList[workerIndex].at(-1);
|
|
70
|
+
if (!lastRangeQuery)
|
|
71
|
+
throw Error('Impossible case, worker does not have any range query');
|
|
72
|
+
const newQueryEnd = Math.floor((lastRangeQuery.end - lastRangeQuery.start) / 2) +
|
|
73
|
+
lastRangeQuery.start;
|
|
74
|
+
this.logger.debug(`Limiting the range by adding a new range query [${(lastRangeQuery.start, newQueryEnd)}]`);
|
|
75
|
+
await this.addWorkerRange(workerIndex, lastRangeQuery.start, newQueryEnd);
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Pop the last range query after being processed
|
|
79
|
+
* also update all older ranges and deduct the processed numbers
|
|
80
|
+
* @param workerIndex
|
|
81
|
+
*/
|
|
82
|
+
popLastRangeQuery = async (workerIndex) => {
|
|
83
|
+
const release = await this.mutex.acquire();
|
|
84
|
+
const lastRangeQuery = this.workersRangeList[workerIndex].pop();
|
|
85
|
+
if (!lastRangeQuery)
|
|
86
|
+
throw Error('Impossible case, worker does not have any range query');
|
|
87
|
+
this.workersRangeList[workerIndex].map((rangeQuery) => {
|
|
88
|
+
rangeQuery.count -= lastRangeQuery.count;
|
|
89
|
+
rangeQuery.start = lastRangeQuery.end + 1;
|
|
90
|
+
});
|
|
91
|
+
release();
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Find the biggest incomplete range list containing at least 2 ranges
|
|
95
|
+
* the range list must have at least two range so that it wont become empty
|
|
96
|
+
* after splitting the range between two workers
|
|
97
|
+
* @returns biggest incomplete range list index
|
|
98
|
+
*/
|
|
99
|
+
getBiggestIncompleteRangeIndex = () => {
|
|
100
|
+
let biggestRange = 0, biggestRangeIndex = undefined;
|
|
101
|
+
for (let i = 0; i < this.workersRangeList.length; i++) {
|
|
102
|
+
const rangeList = this.workersRangeList[i];
|
|
103
|
+
if (rangeList.length > 1 && rangeList[0].count > biggestRange) {
|
|
104
|
+
biggestRange = rangeList[0].count;
|
|
105
|
+
biggestRangeIndex = i;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return biggestRangeIndex;
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Check all workers and reassign incomplete ranges to the idle ones
|
|
112
|
+
* do nothing if all workers are active
|
|
113
|
+
* do nothing if there is no incomplete range list
|
|
114
|
+
* split the biggest range list between the current worker and the idle worker
|
|
115
|
+
* @returns
|
|
116
|
+
*/
|
|
117
|
+
reassignIdleWorkers = async () => {
|
|
118
|
+
this.logger.debug('Checking idle workers to reassign');
|
|
119
|
+
const release = await this.mutex.acquire();
|
|
120
|
+
const idleWorkerIndexes = this.workersRangeList
|
|
121
|
+
.map((_, index) => (this.isWorkerActive(index) ? -1 : index))
|
|
122
|
+
.filter((index) => index !== -1);
|
|
123
|
+
if (idleWorkerIndexes.length == 0) {
|
|
124
|
+
this.logger.debug(`There is no idle worker to reassign`);
|
|
125
|
+
release();
|
|
126
|
+
return [];
|
|
127
|
+
}
|
|
128
|
+
this.logger.debug(`Found idle workers ${idleWorkerIndexes}`);
|
|
129
|
+
this.logger.debug(`Workers range lists before splitting ${JSON.stringify(this.workersRangeList)}`);
|
|
130
|
+
const newWorkers = [];
|
|
131
|
+
for (const idleWorkerIndex of idleWorkerIndexes) {
|
|
132
|
+
this.logger.debug(`reassigning job to worker-${idleWorkerIndex}`);
|
|
133
|
+
const biggestIncompleteRangeIndex = this.getBiggestIncompleteRangeIndex();
|
|
134
|
+
if (biggestIncompleteRangeIndex == undefined) {
|
|
135
|
+
this.logger.debug(`there is no incomplete range to reassign`);
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
this.logger.debug(`biggest incomplete range is ${JSON.stringify(this.workersRangeList[biggestIncompleteRangeIndex])}`);
|
|
139
|
+
const removedRangeQuery = this.workersRangeList[biggestIncompleteRangeIndex].shift();
|
|
140
|
+
const head = this.workersRangeList[biggestIncompleteRangeIndex][0];
|
|
141
|
+
this.workersRangeList[idleWorkerIndex] = [
|
|
142
|
+
{
|
|
143
|
+
start: head.end + 1,
|
|
144
|
+
end: removedRangeQuery.end,
|
|
145
|
+
count: removedRangeQuery.count - head.count,
|
|
146
|
+
},
|
|
147
|
+
];
|
|
148
|
+
newWorkers.push(idleWorkerIndex);
|
|
149
|
+
}
|
|
150
|
+
release();
|
|
151
|
+
this.logger.debug(`Range lists after splitting ${JSON.stringify(this.workersRangeList)}`);
|
|
152
|
+
return newWorkers;
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* Get the last (biggest) processable range from the worker's range list
|
|
156
|
+
*
|
|
157
|
+
* After the last range is processed, the older ones are updated and usually
|
|
158
|
+
* become smaller. Some of them might shrink below a certain threshold, which
|
|
159
|
+
* means they can now be processed too.
|
|
160
|
+
* This function finds the biggest range that is small enough to be processed,
|
|
161
|
+
* and removes all of its child ranges from the list.
|
|
162
|
+
* Returns the last range if none of them is processable.
|
|
163
|
+
* @param workerIndex
|
|
164
|
+
* @param rangeThreshold
|
|
165
|
+
* @returns range query
|
|
166
|
+
*/
|
|
167
|
+
getLastRange = async (workerIndex, rangeThreshold) => {
|
|
168
|
+
const rangeList = this.workersRangeList[workerIndex];
|
|
169
|
+
this.logger.debug(`Search range of worker-${workerIndex} is ${JSON.stringify(rangeList)}`);
|
|
170
|
+
let lastRangeQuery = rangeList.at(-1);
|
|
171
|
+
// avoid race condition when updating the shared `rangeList` variable
|
|
172
|
+
const release = await this.mutex.acquire();
|
|
173
|
+
// jump over small ranges to select the biggest processable range
|
|
174
|
+
while (rangeList.length > 1 &&
|
|
175
|
+
(rangeList.at(-2).count <= rangeThreshold || lastRangeQuery.count == 0)) {
|
|
176
|
+
rangeList.pop();
|
|
177
|
+
lastRangeQuery = rangeList.at(-1);
|
|
178
|
+
}
|
|
179
|
+
release();
|
|
180
|
+
return lastRangeQuery;
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya2VyTWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2xpYi9lcmdvL2luaXRpYWxpemVycy9zdHJhdGVnaWVzL3dvcmtlck1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRXhDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUk1RCxNQUFNLE9BQU8sYUFBYTtJQU9kO0lBQ0E7SUFDQTtJQVJGLGdCQUFnQixDQUFjO0lBQzlCLEtBQUssR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFDO0lBQ3BCLGtCQUFrQixDQUFTO0lBQzNCLFNBQVMsQ0FBVTtJQUUzQixZQUNVLFdBQW1CLEVBQ25CLGVBQWdFLEVBQ2hFLFNBQVMsSUFBSSxXQUFXLEVBQUU7UUFGMUIsZ0JBQVcsR0FBWCxXQUFXLENBQVE7UUFDbkIsb0JBQWUsR0FBZixlQUFlLENBQWlEO1FBQ2hFLFdBQU0sR0FBTixNQUFNLENBQW9CO0lBQ2pDLENBQUM7SUFFSjs7O09BR0c7SUFDSCxLQUFLLEdBQUcsQ0FBQyxTQUFpQixFQUFFLEVBQUU7UUFDNUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7UUFDM0IsSUFBSSxDQUFDLGdCQUFnQixHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLFdBQVcsRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzNFLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3pFLENBQUMsQ0FBQztJQUVGOzs7O09BSUc7SUFDSCxjQUFjLEdBQUcsQ0FBQyxXQUFtQixFQUFXLEVBQUU7UUFDaEQsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENB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QUMsQ0FBRSxDQUFDLEtBQUssSUFBSSxjQUFjLElBQUksY0FBYyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsRUFDeEUsQ0FBQztZQUNELFNBQVMsQ0FBQyxHQUFHLEVBQUcsQ0FBQztZQUNqQixjQUFjLEdBQUcsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBRSxDQUFDO1FBQ3JDLENBQUM7UUFDRCxPQUFPLEVBQUUsQ0FBQztRQUNWLE9BQU8sY0FBYyxDQUFDO0lBQ3hCLENBQUMsQ0FBQztDQUNIIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTXV0ZXggfSBmcm9tICdhd2FpdC1zZW1hcGhvcmUnO1xuXG5pbXBvcnQgeyBEdW1teUxvZ2dlciB9IGZyb20gJ0Byb3Nlbi1icmlkZ2UvYWJzdHJhY3QtbG9nZ2VyJztcblxuaW1wb3J0IHsgUmFuZ2VMaXN0LCBSYW5nZVF1ZXJ5IH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcyc7XG5cbmV4cG9ydCBjbGFzcyBXb3JrZXJNYW5hZ2VyIHtcbiAgcHJpdmF0ZSB3b3JrZXJzUmFuZ2VMaXN0OiBSYW5nZUxpc3RbXTtcbiAgcHJpdmF0ZSBtdXRleCA9IG5ldyBNdXRleCgpO1xuICBwcml2YXRlIGluaXRpYWxTZWdtZW50U2l6ZTogbnVtYmVyO1xuICBwcml2YXRlIG1heEhlaWdodD86IG51bWJlcjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHdvcmtlckNvdW50OiBudW1iZXIsXG4gICAgcHJpdmF0ZSBnZXRSYW5nZVR4Q291bnQ6IChzdGFydDogbnVtYmVyLCBlbmQ6IG51bWJlcikgPT4gUHJvbWlzZTxudW1iZXI+LFxuICAgIHByaXZhdGUgbG9nZ2VyID0gbmV3IER1bW15TG9nZ2VyKCksXG4gICkge31cblxuICAvKipcbiAgICogU2V0dXAgdGhlIHdvcmtlciBtYW5hZ2VyIHRvIHN0YXJ0IHdvcmtpbmdcbiAgICogQHBhcmFtIG1heEhlaWdodFxuICAgKi9cbiAgc2V0dXAgPSAobWF4SGVpZ2h0OiBudW1iZXIpID0+IHtcbiAgICB0aGlzLm1heEhlaWdodCA9IG1heEhlaWdodDtcbiAgICB0aGlzLndvcmtlcnNSYW5nZUxpc3QgPSBBcnJheS5mcm9tKHsgbGVuZ3RoOiB0aGlzLndvcmtlckNvdW50IH0sICgpID0+IFtdKTtcbiAgICB0aGlzLmluaXRpYWxTZWdtZW50U2l6ZSA9IE1hdGguY2VpbCh0aGlzLm1heEhlaWdodCAvIHRoaXMud29ya2VyQ291bnQpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIHdvcmtlcidzIHNlYXJjaCByYW5nZSBpcyBjb21wbGV0ZWRcbiAgICogQHBhcmFtIHdvcmtlckluZGV4XG4gICAqIEByZXR1cm5zIHRydWUgaWYgd29ya2VyIGhhcyBhbiBpbmNvbXBsZXRlIHJhbmdlIHRvIHdvcmsgb25cbiAgICovXG4gIGlzV29ya2VyQWN0aXZlID0gKHdvcmtlckluZGV4OiBudW1iZXIpOiBib29sZWFuID0+IHtcbiAgICByZXR1cm4gdGhpcy53b3JrZXJzUmFuZ2VMaXN0W3dvcmtlckluZGV4XS5sZW5ndGggPiAwO1xuICB9O1xuXG4gIC8qKlxuICAgKiBSZWdpc3RlciB0aGUgd29ya2VyIGZvciB0aGUgZmlyc3QgdGltZVxuICAgKiBzcGxpdHMgdGhlIHdob2xlIHJhbmdlIGVxdWFsbHkgYmV0d2VlbiB3b3JrZXJzXG4gICAqIEBwYXJhbSB3b3JrZXJJbmRleFxuICAgKi9cbiAgcmVnaXN0ZXJXb3JrZXIgPSBhc3luYyAod29ya2VySW5kZXg6IG51bWJlcikgPT4ge1xuICAgIGlmICghdGhpcy5tYXhIZWlnaHQpXG4gICAgICB0aHJvdyBFcnJvcignUGxlYXNlIGNhbGwgc2V0dXAgYmVmb3JlIHJlZ2lzdGVyaW5nIHdvcmtlcnMnKTtcbiAgICBjb25zdCBzdGFydCA9IHdvcmtlckluZGV4ICogdGhpcy5pbml0aWFsU2VnbWVudFNpemU7XG4gICAgY29uc3QgZW5kID0gTWF0aC5taW4oXG4gICAgICAod29ya2VySW5kZXggKyAxKSAqIHRoaXMuaW5pdGlhbFNlZ21lbnRTaXplIC0gMSxcbiAgICAgIHRoaXMubWF4SGVpZ2h0LFxuICAgICk7XG4gICAgYXdhaXQgdGhpcy5hZGRXb3JrZXJSYW5nZSh3b3JrZXJJbmRleCwgc3RhcnQsIGVuZCk7XG4gICAgdGhpcy5sb2dnZXIuZGVidWcoXG4gICAgICBgV29ya2VyLSR7d29ya2VySW5kZXh9IGlzIGluaXRpYWxpemVkIHdpdGggcmFuZ2UgWyR7c3RhcnR9LCAke2VuZH1dYCxcbiAgICApO1xuICB9O1xuXG4gIC8qKlxuICAgKiBBZGQgYSBuZXcgcmFuZ2UgdG8gdGhlIHdvcmtlcnMgcmFuZ2UgbGlzdFxuICAgKiBuZXcgcmFuZ2UgaXMgYSBzdWJzZXQgb2YgYWxsIGV4aXN0aW5nIHJhbmdlc1xuICAgKiBAcGFyYW0gd29ya2VySW5kZXhcbiAgICogQHBhcmFtIHN0YXJ0XG4gICAqIEBwYXJhbSBlbmRcbiAgICovXG4gIHByaXZhdGUgYWRkV29ya2VyUmFuZ2UgPSBhc3luYyAoXG4gICAgd29ya2VySW5kZXg6IG51bWJlcixcbiAgICBzdGFydDogbnVtYmVyLFxuICAgIGVuZDogbnVtYmVyLFxuICApID0+IHtcbiAgICBjb25zdCBjb3VudCA9IGF3YWl0IHRoaXMuZ2V0UmFuZ2VUeENvdW50KHN0YXJ0LCBlbmQpO1xuICAgIGNvbnN0IHJlbGVhc2UgPSBhd2FpdCB0aGlzLm11dGV4LmFjcXVpcmUoKTtcbiAgICB0aGlzLndvcmtlcnNSYW5nZUxpc3Rbd29ya2VySW5kZXhdLnB1c2goe1xuICAgICAgc3RhcnQsXG4gICAgICBlbmQsXG4gICAgICBjb3VudCxcbiAgICB9KTtcbiAgICByZWxlYXNlKCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIExpbWl0IHRoZSBsYXN0IHJhbmdlIGJ5IGFkZGluZyBhIG5ldyByYW5nZSBxdWVyeSB0byB0aGUgd29ya2VycyByYW5nZSBsaXN0XG4gICAqIHRoZSBuZXcgcmFuZ2UgdGhlIGZpcnN0IGhhbGYgb2YgdGhlIGxhc3QgZXhpc3RpbmcgcmFuZ2VcbiAgICogQHBhcmFtIHdvcmtlckluZGV4XG4gICAqL1xuICBsaW1pdExhc3RSYW5nZSA9IGFzeW5jICh3b3JrZXJJbmRleDogbnVtYmVyKSA9PiB7XG4gICAgY29uc3QgbGFzdFJhbmdlUXVlcnkgPSB0aGlzLndvcmtlcnNSYW5nZUxpc3Rbd29ya2VySW5kZXhdLmF0KC0xKTtcbiAgICBpZiAoIWxhc3RSYW5nZVF1ZXJ5KVxuICAgICAgdGhyb3cgRXJyb3IoJ0ltcG9zc2libGUgY2FzZSwgd29ya2VyIGRvZXMgbm90IGhhdmUgYW55IHJhbmdlIHF1ZXJ5Jyk7XG4gICAgY29uc3QgbmV3UXVlcnlFbmQgPVxuICAgICAgTWF0aC5mbG9vcigobGFzdFJhbmdlUXVlcnkuZW5kIC0gbGFzdFJhbmdlUXVlcnkuc3RhcnQpIC8gMikgK1xuICAgICAgbGFzdFJhbmdlUXVlcnkuc3RhcnQ7XG4gICAgdGhpcy5sb2dnZXIuZGVidWcoXG4gICAgICBgTGltaXRpbmcgdGhlIHJhbmdlIGJ5IGFkZGluZyBhIG5ldyByYW5nZSBxdWVyeSBbJHtcbiAgICAgICAgKGxhc3RSYW5nZVF1ZXJ5LnN0YXJ0LCBuZXdRdWVyeUVuZClcbiAgICAgIH1dYCxcbiAgICApO1xuICAgIGF3YWl0IHRoaXMuYWRkV29ya2VyUmFuZ2Uod29ya2VySW5kZXgsIGxhc3RSYW5nZVF1ZXJ5LnN0YXJ0LCBuZXdRdWVyeUVuZCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFBvcCB0aGUgbGFzdCByYW5nZSBxdWVyeSBhZnRlciBiZWluZyBwcm9jZXNzZWRcbiAgICogYWxzbyB1cGRhdGUgYWxsIG9sZGVyIHJhbmdlcyBhbmQgZGVkdWN0IHRoZSBwcm9jZXNzZWQgbnVtYmVyc1xuICAgKiBAcGFyYW0gd29ya2VySW5kZXhcbiAgICovXG4gIHBvcExhc3RSYW5nZVF1ZXJ5ID0gYXN5bmMgKHdvcmtlckluZGV4OiBudW1iZXIpID0+IHtcbiAgICBjb25zdCByZWxlYXNlID0gYXdhaXQgdGhpcy5tdXRleC5hY3F1aXJlKCk7XG4gICAgY29uc3QgbGFzdFJhbmdlUXVlcnkgPSB0aGlzLndvcmtlcnNSYW5nZUxpc3Rbd29ya2VySW5kZXhdLnBvcCgpO1xuICAgIGlmICghbGFzdFJhbmdlUXVlcnkpXG4gICAgICB0aHJvdyBFcnJvcignSW1wb3NzaWJsZSBjYXNlLCB3b3JrZXIgZG9lcyBub3QgaGF2ZSBhbnkgcmFuZ2UgcXVlcnknKTtcbiAgICB0aGlzLndvcmtlcnNSYW5nZUxpc3Rbd29ya2VySW5kZXhdLm1hcCgocmFuZ2VRdWVyeSkgPT4ge1xuICAgICAgcmFuZ2VRdWVyeS5jb3VudCAtPSBsYXN0UmFuZ2VRdWVyeS5jb3VudDtcbiAgICAgIHJhbmdlUXVlcnkuc3RhcnQgPSBsYXN0UmFuZ2VRdWVyeS5lbmQgKyAxO1xuICAgIH0pO1xuICAgIHJlbGVhc2UoKTtcbiAgfTtcblxuICAvKipcbiAgICogRmluZCB0aGUgYmlnZ2VzdCBpbmNvbXBsZXRlIHJhbmdlIGxpc3QgY29udGFpbmluZyBhdCBsZWFzdCAyIHJhbmdlc1xuICAgKiB0aGUgcmFuZ2UgbGlzdCBtdXN0IGhhdmUgYXQgbGVhc3QgdHdvIHJhbmdlIHNvIHRoYXQgaXQgd29udCBiZWNvbWUgZW1wdHlcbiAgICogYWZ0ZXIgc3BsaXR0aW5nIHRoZSByYW5nZSBiZXR3ZWVuIHR3byB3b3JrZXJzXG4gICAqIEByZXR1cm5zIGJpZ2dlc3QgaW5jb21wbGV0ZSByYW5nZSBsaXN0IGluZGV4XG4gICAqL1xuICBwcml2YXRlIGdldEJpZ2dlc3RJbmNvbXBsZXRlUmFuZ2VJbmRleCA9ICgpOiBudW1iZXIgfCB1bmRlZmluZWQgPT4ge1xuICAgIGxldCBiaWdnZXN0UmFuZ2UgPSAwLFxuICAgICAgYmlnZ2VzdFJhbmdlSW5kZXggPSB1bmRlZmluZWQ7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLndvcmtlcnNSYW5nZUxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHJhbmdlTGlzdCA9IHRoaXMud29ya2Vyc1JhbmdlTGlzdFtpXTtcbiAgICAgIGlmIChyYW5nZUxpc3QubGVuZ3RoID4gMSAmJiByYW5nZUxpc3RbMF0uY291bnQgPiBiaWdnZXN0UmFuZ2UpIHtcbiAgICAgICAgYmlnZ2VzdFJhbmdlID0gcmFuZ2VMaXN0WzBdLmNvdW50O1xuICAgICAgICBiaWdnZXN0UmFuZ2VJbmRleCA9IGk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBiaWdnZXN0UmFuZ2VJbmRleDtcbiAgfTtcblxuICAvKipcbiAgICogQ2hlY2sgYWxsIHdvcmtlcnMgYW5kIHJlYXNzaWduIGluY29tcGxldGUgcmFuZ2VzIHRvIHRoZSBpZGxlIG9uZXNcbiAgICogZG8gbm90aGluZyBpZiBhbGwgd29ya2VycyBhcmUgYWN0aXZlXG4gICAqIGRvIG5vdGhpbmcgaWYgdGhlcmUgaXMgbm8gaW5jb21wbGV0ZSByYW5nZSBsaXN0XG4gICAqIHNwbGl0IHRoZSBiaWdnZXN0IHJhbmdlIGxpc3QgYmV0d2VlbiB0aGUgY3VycmVudCB3b3JrZXIgYW5kIHRoZSBpZGxlIHdvcmtlclxuICAgKiBAcmV0dXJuc1xuICAgKi9cbiAgcmVhc3NpZ25JZGxlV29ya2VycyA9IGFzeW5jICgpOiBQcm9taXNlPG51bWJlcltdPiA9PiB7XG4gICAgdGhpcy5sb2dnZXIuZGVidWcoJ0NoZWNraW5nIGlkbGUgd29ya2VycyB0byByZWFzc2lnbicpO1xuICAgIGNvbnN0IHJlbGVhc2UgPSBhd2FpdCB0aGlzLm11dGV4LmFjcXVpcmUoKTtcbiAgICBjb25zdCBpZGxlV29ya2VySW5kZXhlcyA9IHRoaXMud29ya2Vyc1JhbmdlTGlzdFxuICAgICAgLm1hcCgoXywgaW5kZXgpID0+ICh0aGlzLmlzV29ya2VyQWN0aXZlKGluZGV4KSA/IC0xIDogaW5kZXgpKVxuICAgICAgLmZpbHRlcigoaW5kZXgpID0+IGluZGV4ICE9PSAtMSk7XG4gICAgaWYgKGlkbGVXb3JrZXJJbmRleGVzLmxlbmd0aCA9PSAwKSB7XG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgVGhlcmUgaXMgbm8gaWRsZSB3b3JrZXIgdG8gcmVhc3NpZ25gKTtcbiAgICAgIHJlbGVhc2UoKTtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgdGhpcy5sb2dnZXIuZGVidWcoYEZvdW5kIGlkbGUgd29ya2VycyAke2lkbGVXb3JrZXJJbmRleGVzfWApO1xuICAgIHRoaXMubG9nZ2VyLmRlYnVnKFxuICAgICAgYFdvcmtlcnMgcmFuZ2UgbGlzdHMgYmVmb3JlIHNwbGl0dGluZyAke0pTT04uc3RyaW5naWZ5KFxuICAgICAgICB0aGlzLndvcmtlcnNSYW5nZUxpc3QsXG4gICAgICApfWAsXG4gICAgKTtcbiAgICBjb25zdCBuZXdXb3JrZXJzOiBudW1iZXJbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgaWRsZVdvcmtlckluZGV4IG9mIGlkbGVXb3JrZXJJbmRleGVzKSB7XG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgcmVhc3NpZ25pbmcgam9iIHRvIHdvcmtlci0ke2lkbGVXb3JrZXJJbmRleH1gKTtcbiAgICAgIGNvbnN0IGJpZ2dlc3RJbmNvbXBsZXRlUmFuZ2VJbmRleCA9IHRoaXMuZ2V0QmlnZ2VzdEluY29tcGxldGVSYW5nZUluZGV4KCk7XG4gICAgICBpZiAoYmlnZ2VzdEluY29tcGxldGVSYW5nZUluZGV4ID09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgdGhlcmUgaXMgbm8gaW5jb21wbGV0ZSByYW5nZSB0byByZWFzc2lnbmApO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKFxuICAgICAgICBgYmlnZ2VzdCBpbmNvbXBsZXRlIHJhbmdlIGlzICR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgdGhpcy53b3JrZXJzUmFuZ2VMaXN0W2JpZ2dlc3RJbmNvbXBsZXRlUmFuZ2VJbmRleF0sXG4gICAgICAgICl9YCxcbiAgICAgICk7XG4gICAgICBjb25zdCByZW1vdmVkUmFuZ2VRdWVyeSA9XG4gICAgICAgIHRoaXMud29ya2Vyc1JhbmdlTGlzdFtiaWdnZXN0SW5jb21wbGV0ZVJhbmdlSW5kZXhdLnNoaWZ0KCkhO1xuICAgICAgY29uc3QgaGVhZCA9IHRoaXMud29ya2Vyc1JhbmdlTGlzdFtiaWdnZXN0SW5jb21wbGV0ZVJhbmdlSW5kZXhdWzBdO1xuICAgICAgdGhpcy53b3JrZXJzUmFuZ2VMaXN0W2lkbGVXb3JrZXJJbmRleF0gPSBbXG4gICAgICAgIHtcbiAgICAgICAgICBzdGFydDogaGVhZC5lbmQgKyAxLFxuICAgICAgICAgIGVuZDogcmVtb3ZlZFJhbmdlUXVlcnkuZW5kLFxuICAgICAgICAgIGNvdW50OiByZW1vdmVkUmFuZ2VRdWVyeS5jb3VudCAtIGhlYWQuY291bnQsXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgICAgbmV3V29ya2Vycy5wdXNoKGlkbGVXb3JrZXJJbmRleCk7XG4gICAgfVxuICAgIHJlbGVhc2UoKTtcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcbiAgICAgIGBSYW5nZSBsaXN0cyBhZnRlciBzcGxpdHRpbmcgJHtKU09OLnN0cmluZ2lmeSh0aGlzLndvcmtlcnNSYW5nZUxpc3QpfWAsXG4gICAgKTtcbiAgICByZXR1cm4gbmV3V29ya2VycztcbiAgfTtcblxuICAvKipcbiAgICogR2V0IHRoZSBsYXN0IChiaWdnZXN0KSBwcm9jZXNzYWJsZSByYW5nZSBmcm9tIHRoZSB3b3JrZXIncyByYW5nZSBsaXN0XG4gICAqXG4gICAqIEFmdGVyIHRoZSBsYXN0IHJhbmdlIGlzIHByb2Nlc3NlZCwgdGhlIG9sZGVyIG9uZXMgYXJlIHVwZGF0ZWQgYW5kIHVzdWFsbHlcbiAgICogYmVjb21lIHNtYWxsZXIuIFNvbWUgb2YgdGhlbSBtaWdodCBzaHJpbmsgYmVsb3cgYSBjZXJ0YWluIHRocmVzaG9sZCwgd2hpY2hcbiAgICogbWVhbnMgdGhleSBjYW4gbm93IGJlIHByb2Nlc3NlZCB0b28uXG4gICAqIFRoaXMgZnVuY3Rpb24gZmluZHMgdGhlIGJpZ2dlc3QgcmFuZ2UgdGhhdCBpcyBzbWFsbCBlbm91Z2ggdG8gYmUgcHJvY2Vzc2VkLFxuICAgKiBhbmQgcmVtb3ZlcyBhbGwgb2YgaXRzIGNoaWxkIHJhbmdlcyBmcm9tIHRoZSBsaXN0LlxuICAgKiBSZXR1cm5zIHRoZSBsYXN0IHJhbmdlIGlmIG5vbmUgb2YgdGhlbSBpcyBwcm9jZXNzYWJsZS5cbiAgICogQHBhcmFtIHdvcmtlckluZGV4XG4gICAqIEBwYXJhbSByYW5nZVRocmVzaG9sZFxuICAgKiBAcmV0dXJucyByYW5nZSBxdWVyeVxuICAgKi9cbiAgZ2V0TGFzdFJhbmdlID0gYXN5bmMgKFxuICAgIHdvcmtlckluZGV4OiBudW1iZXIsXG4gICAgcmFuZ2VUaHJlc2hvbGQ6IG51bWJlcixcbiAgKTogUHJvbWlzZTxSYW5nZVF1ZXJ5PiA9PiB7XG4gICAgY29uc3QgcmFuZ2VMaXN0ID0gdGhpcy53b3JrZXJzUmFuZ2VMaXN0W3dvcmtlckluZGV4XTtcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcbiAgICAgIGBTZWFyY2ggcmFuZ2Ugb2Ygd29ya2VyLSR7d29ya2VySW5kZXh9IGlzICR7SlNPTi5zdHJpbmdpZnkocmFuZ2VMaXN0KX1gLFxuICAgICk7XG4gICAgbGV0IGxhc3RSYW5nZVF1ZXJ5ID0gcmFuZ2VMaXN0LmF0KC0xKSE7XG4gICAgLy8gYXZvaWQgcmFjZSBjb25kaXRpb24gd2hlbiB1cGRhdGluZyB0aGUgc2hhcmVkIGByYW5nZUxpc3RgIHZhcmlhYmxlXG4gICAgY29uc3QgcmVsZWFzZSA9IGF3YWl0IHRoaXMubXV0ZXguYWNxdWlyZSgpO1xuICAgIC8vIGp1bXAgb3ZlciBzbWFsbCByYW5nZXMgdG8gc2VsZWN0IHRoZSBiaWdnZXN0IHByb2Nlc3NhYmxlIHJhbmdlXG4gICAgd2hpbGUgKFxuICAgICAgcmFuZ2VMaXN0Lmxlbmd0aCA+IDEgJiZcbiAgICAgIChyYW5nZUxpc3QuYXQoLTIpIS5jb3VudCA8PSByYW5nZVRocmVzaG9sZCB8fCBsYXN0UmFuZ2VRdWVyeS5jb3VudCA9PSAwKVxuICAgICkge1xuICAgICAgcmFuZ2VMaXN0LnBvcCgpITtcbiAgICAgIGxhc3RSYW5nZVF1ZXJ5ID0gcmFuZ2VMaXN0LmF0KC0xKSE7XG4gICAgfVxuICAgIHJlbGVhc2UoKTtcbiAgICByZXR1cm4gbGFzdFJhbmdlUXVlcnk7XG4gIH07XG59XG4iXX0=
|
|
@@ -1,15 +1,8 @@
|
|
|
1
|
-
import { OutputBox, Transaction } from '@rosen-bridge/scanner-interfaces';
|
|
2
|
-
export interface ErgoBox extends OutputBox {
|
|
3
|
-
blockId: string;
|
|
4
|
-
inclusionHeight: number;
|
|
5
|
-
spentBlockId?: string;
|
|
6
|
-
spentHeight?: number;
|
|
7
|
-
spentTransactionId?: string;
|
|
8
|
-
spentIndex?: number;
|
|
9
|
-
}
|
|
1
|
+
import { ErgoNetworkType, OutputBox, Transaction } from '@rosen-bridge/scanner-interfaces';
|
|
10
2
|
export interface ExtendedTransaction extends Transaction {
|
|
11
3
|
inclusionHeight: number;
|
|
12
4
|
blockId: string;
|
|
5
|
+
inputs: OutputBox[];
|
|
13
6
|
}
|
|
14
7
|
export interface SpendInfo {
|
|
15
8
|
boxId: string;
|
|
@@ -19,8 +12,12 @@ export interface SpendInfo {
|
|
|
19
12
|
[key: string]: string;
|
|
20
13
|
};
|
|
21
14
|
}
|
|
22
|
-
export interface
|
|
23
|
-
|
|
15
|
+
export interface ExtendedSpendInfo extends SpendInfo {
|
|
16
|
+
height: number;
|
|
17
|
+
block: string;
|
|
18
|
+
}
|
|
19
|
+
export interface AbstractEntityData {
|
|
20
|
+
identifier: string;
|
|
24
21
|
serialized: string;
|
|
25
22
|
}
|
|
26
23
|
export declare enum CallbackType {
|
|
@@ -29,19 +26,36 @@ export declare enum CallbackType {
|
|
|
29
26
|
Spend = "spend",
|
|
30
27
|
Delete = "delete"
|
|
31
28
|
}
|
|
32
|
-
export interface
|
|
33
|
-
|
|
29
|
+
export interface EntityInfo {
|
|
30
|
+
identifier: string;
|
|
34
31
|
}
|
|
35
|
-
export type CallbackDataMap<ExtractedData extends
|
|
36
|
-
[CallbackType.Update]:
|
|
32
|
+
export type CallbackDataMap<ExtractedData extends AbstractEntityData> = {
|
|
33
|
+
[CallbackType.Update]: EntityInfo[];
|
|
37
34
|
[CallbackType.Insert]: ExtractedData[];
|
|
38
35
|
[CallbackType.Delete]: ExtractedData[];
|
|
39
|
-
[CallbackType.Spend]:
|
|
36
|
+
[CallbackType.Spend]: EntityInfo[];
|
|
40
37
|
};
|
|
41
|
-
export type CallbackMap<ExtractedData extends
|
|
38
|
+
export type CallbackMap<ExtractedData extends AbstractEntityData> = {
|
|
42
39
|
[K in CallbackType]: (data: CallbackDataMap<ExtractedData>[K]) => void;
|
|
43
40
|
};
|
|
44
41
|
export type TxExtra = {
|
|
45
42
|
[key: string]: string;
|
|
46
43
|
};
|
|
44
|
+
export interface RangeQuery {
|
|
45
|
+
start: number;
|
|
46
|
+
end: number;
|
|
47
|
+
count: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The range list is an array where each new range is a child of the previous
|
|
51
|
+
* one. So, any range in the list supersedes all the ranges that come after it.
|
|
52
|
+
* */
|
|
53
|
+
export type RangeList = RangeQuery[];
|
|
54
|
+
export interface InitializeOptions {
|
|
55
|
+
active: boolean;
|
|
56
|
+
type: ErgoNetworkType;
|
|
57
|
+
url: string;
|
|
58
|
+
address: string;
|
|
59
|
+
maxParallelRequests?: number;
|
|
60
|
+
}
|
|
47
61
|
//# sourceMappingURL=interfaces.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../../lib/ergo/interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../../lib/ergo/interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,SAAS,EACT,WAAW,EACZ,MAAM,kCAAkC,CAAC;AAE1C,MAAM,WAAW,mBAAoB,SAAQ,WAAW;IACtD,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,SAAS,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CACpC;AAED,MAAM,WAAW,iBAAkB,SAAQ,SAAS;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AACD,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,oBAAY,YAAY;IACtB,MAAM,WAAW;IACjB,MAAM,WAAW;IACjB,KAAK,UAAU;IACf,MAAM,WAAW;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,eAAe,CAAC,aAAa,SAAS,kBAAkB,IAAI;IACtE,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;IACpC,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;IACvC,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;IACvC,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,aAAa,SAAS,kBAAkB,IAAI;KACjE,CAAC,IAAI,YAAY,GAAG,CAAC,IAAI,EAAE,eAAe,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI;CACvE,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC;AAEhD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;KAGK;AACL,MAAM,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC;AAErC,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,eAAe,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B"}
|
package/dist/ergo/interfaces.js
CHANGED
|
@@ -5,4 +5,4 @@ export var CallbackType;
|
|
|
5
5
|
CallbackType["Spend"] = "spend";
|
|
6
6
|
CallbackType["Delete"] = "delete";
|
|
7
7
|
})(CallbackType || (CallbackType = {}));
|
|
8
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJmYWNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL2xpYi9lcmdvL2ludGVyZmFjZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBNEJBLE1BQU0sQ0FBTixJQUFZLFlBS1g7QUFMRCxXQUFZLFlBQVk7SUFDdEIsaUNBQWlCLENBQUE7SUFDakIsaUNBQWlCLENBQUE7SUFDakIsK0JBQWUsQ0FBQTtJQUNmLGlDQUFpQixDQUFBO0FBQ25CLENBQUMsRUFMVyxZQUFZLEtBQVosWUFBWSxRQUt2QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEVyZ29OZXR3b3JrVHlwZSxcbiAgT3V0cHV0Qm94LFxuICBUcmFuc2FjdGlvbixcbn0gZnJvbSAnQHJvc2VuLWJyaWRnZS9zY2FubmVyLWludGVyZmFjZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEV4dGVuZGVkVHJhbnNhY3Rpb24gZXh0ZW5kcyBUcmFuc2FjdGlvbiB7XG4gIGluY2x1c2lvbkhlaWdodDogbnVtYmVyO1xuICBibG9ja0lkOiBzdHJpbmc7XG4gIGlucHV0czogT3V0cHV0Qm94W107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3BlbmRJbmZvIHtcbiAgYm94SWQ6IHN0cmluZztcbiAgdHhJZDogc3RyaW5nO1xuICBpbmRleDogbnVtYmVyO1xuICBleHRyYXM/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEV4dGVuZGVkU3BlbmRJbmZvIGV4dGVuZHMgU3BlbmRJbmZvIHtcbiAgaGVpZ2h0OiBudW1iZXI7XG4gIGJsb2NrOiBzdHJpbmc7XG59XG5leHBvcnQgaW50ZXJmYWNlIEFic3RyYWN0RW50aXR5RGF0YSB7XG4gIGlkZW50aWZpZXI6IHN0cmluZztcbiAgc2VyaWFsaXplZDogc3RyaW5nO1xufVxuXG5leHBvcnQgZW51bSBDYWxsYmFja1R5cGUge1xuICBJbnNlcnQgPSAnaW5zZXJ0JyxcbiAgVXBkYXRlID0gJ3VwZGF0ZScsXG4gIFNwZW5kID0gJ3NwZW5kJyxcbiAgRGVsZXRlID0gJ2RlbGV0ZScsXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRW50aXR5SW5mbyB7XG4gIGlkZW50aWZpZXI6IHN0cmluZztcbn1cblxuZXhwb3J0IHR5cGUgQ2FsbGJhY2tEYXRhTWFwPEV4dHJhY3RlZERhdGEgZXh0ZW5kcyBBYnN0cmFjdEVudGl0eURhdGE+ID0ge1xuICBbQ2FsbGJhY2tUeXBlLlVwZGF0ZV06IEVudGl0eUluZm9bXTtcbiAgW0NhbGxiYWNrVHlwZS5JbnNlcnRdOiBFeHRyYWN0ZWREYXRhW107XG4gIFtDYWxsYmFja1R5cGUuRGVsZXRlXTogRXh0cmFjdGVkRGF0YVtdO1xuICBbQ2FsbGJhY2tUeXBlLlNwZW5kXTogRW50aXR5SW5mb1tdO1xufTtcblxuZXhwb3J0IHR5cGUgQ2FsbGJhY2tNYXA8RXh0cmFjdGVkRGF0YSBleHRlbmRzIEFic3RyYWN0RW50aXR5RGF0YT4gPSB7XG4gIFtLIGluIENhbGxiYWNrVHlwZV06IChkYXRhOiBDYWxsYmFja0RhdGFNYXA8RXh0cmFjdGVkRGF0YT5bS10pID0+IHZvaWQ7XG59O1xuXG5leHBvcnQgdHlwZSBUeEV4dHJhID0geyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfTtcblxuZXhwb3J0IGludGVyZmFjZSBSYW5nZVF1ZXJ5IHtcbiAgc3RhcnQ6IG51bWJlcjtcbiAgZW5kOiBudW1iZXI7XG4gIGNvdW50OiBudW1iZXI7XG59XG5cbi8qKlxuICogVGhlIHJhbmdlIGxpc3QgaXMgYW4gYXJyYXkgd2hlcmUgZWFjaCBuZXcgcmFuZ2UgaXMgYSBjaGlsZCBvZiB0aGUgcHJldmlvdXNcbiAqIG9uZS4gU28sIGFueSByYW5nZSBpbiB0aGUgbGlzdCBzdXBlcnNlZGVzIGFsbCB0aGUgcmFuZ2VzIHRoYXQgY29tZSBhZnRlciBpdC5cbiAqICovXG5leHBvcnQgdHlwZSBSYW5nZUxpc3QgPSBSYW5nZVF1ZXJ5W107XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5pdGlhbGl6ZU9wdGlvbnMge1xuICBhY3RpdmU6IGJvb2xlYW47XG4gIHR5cGU6IEVyZ29OZXR3b3JrVHlwZTtcbiAgdXJsOiBzdHJpbmc7XG4gIGFkZHJlc3M6IHN0cmluZztcbiAgbWF4UGFyYWxsZWxSZXF1ZXN0cz86IG51bWJlcjtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Transaction } from '@rosen-bridge/scanner-interfaces';
|
|
2
|
+
import { ExtendedTransaction } from '../interfaces';
|
|
3
|
+
export declare class ExplorerNetwork {
|
|
4
|
+
private api;
|
|
5
|
+
constructor(url: string);
|
|
6
|
+
/**
|
|
7
|
+
* convert explorer api output boxes to OutputBox interface
|
|
8
|
+
* @param box
|
|
9
|
+
* @returns OutputBox
|
|
10
|
+
*/
|
|
11
|
+
private convertOutputBox;
|
|
12
|
+
/**
|
|
13
|
+
* convert explorer api input boxes to OutputBox interface
|
|
14
|
+
* @param box
|
|
15
|
+
* @returns OutputBox
|
|
16
|
+
*/
|
|
17
|
+
private convertInputBox;
|
|
18
|
+
/**
|
|
19
|
+
* convert explorer transaction to extractor transaction type
|
|
20
|
+
* @param tx
|
|
21
|
+
*/
|
|
22
|
+
private convertTransaction;
|
|
23
|
+
/**
|
|
24
|
+
* convert explorer block transaction to transaction type
|
|
25
|
+
* @param tx
|
|
26
|
+
*/
|
|
27
|
+
private convertBlockTransaction;
|
|
28
|
+
/**
|
|
29
|
+
* use explorer api to return related transactions of the specified address in the height range
|
|
30
|
+
* @param tokenId
|
|
31
|
+
* @param offset
|
|
32
|
+
* @param limit
|
|
33
|
+
* @returns related transactions
|
|
34
|
+
*/
|
|
35
|
+
getAddressTransactionsWithHeight: (address: string, fromHeight: number, toHeight: number, limit?: number) => Promise<{
|
|
36
|
+
items: Array<ExtendedTransaction>;
|
|
37
|
+
total: number;
|
|
38
|
+
}>;
|
|
39
|
+
/**
|
|
40
|
+
* use explorer api to get the block id at the specified height
|
|
41
|
+
* @param height
|
|
42
|
+
* @returns block id
|
|
43
|
+
*/
|
|
44
|
+
getBlockIdAtHeight: (height: number) => Promise<string>;
|
|
45
|
+
/**
|
|
46
|
+
* use explorer api to return all transactions in a block
|
|
47
|
+
* @param blockId
|
|
48
|
+
* @returns converted transactions
|
|
49
|
+
*/
|
|
50
|
+
getBlockTxs: (blockId: string) => Promise<Array<Transaction>>;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=explorerNetwork.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explorerNetwork.d.ts","sourceRoot":"","sources":["../../../lib/ergo/networks/explorerNetwork.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAK1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEpD,qBAAa,eAAe;IAC1B,OAAO,CAAC,GAAG,CAAC;gBAEA,GAAG,EAAE,MAAM;IAIvB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB,CAetB;IAEF;;;;OAIG;IACH,OAAO,CAAC,eAAe,CAerB;IAEF;;;OAGG;IACH,OAAO,CAAC,kBAAkB,CAexB;IAEF;;;OAGG;IACH,OAAO,CAAC,uBAAuB,CAuB7B;IAEF;;;;;;OAMG;IACH,gCAAgC,GAC9B,SAAS,MAAM,EACf,YAAY,MAAM,EAClB,UAAU,MAAM,EAChB,cAAiB,KAChB,OAAO,CAAC;QAAE,KAAK,EAAE,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAc9D;IAEF;;;;OAIG;IACH,kBAAkB,GAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC,CAG1D;IAEF;;;;OAIG;IACH,WAAW,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAUhE;CACH"}
|