@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
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @rosen-bridge/abstract-extractor
|
|
2
2
|
|
|
3
|
+
## 3.0.0-8f3c7016
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- Update AbstractExtractor interface; use `BlockInfo` in `processTransactions` and rename `initializeBoxes` to `initializeData`
|
|
8
|
+
- Update abstract entities and actions to have a new abstraction level, seperating box-based logic from general extraction
|
|
9
|
+
- Update `AbstractErgoExtractor` to use a tx-based data extraction method and add `AbstractErgoBoxExtractor` for box-based data extraction
|
|
10
|
+
- Update abstract database entity to be general; rename `boxId` columnt to `identifier`
|
|
11
|
+
|
|
3
12
|
## 2.1.2
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
|
@@ -1,25 +1,37 @@
|
|
|
1
|
-
import { BlockInfo
|
|
1
|
+
import { BlockInfo } from '@rosen-bridge/scanner-interfaces';
|
|
2
2
|
export declare abstract class AbstractExtractor<TransactionType> {
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* Process a list of transactions (or other blockchain data) in a block and store required information.
|
|
5
|
+
* This method is the core of the extraction process and should be implemented to handle
|
|
6
|
+
* the specific data extraction logic for your blockchain.
|
|
7
|
+
*
|
|
8
|
+
* @param txs - List of transactions or blockchain data structures in the block
|
|
9
|
+
* @param block - Block information containing metadata about the block
|
|
10
|
+
* @returns Promise<boolean> - true if the process completed successfully, false otherwise
|
|
8
11
|
*/
|
|
9
|
-
abstract processTransactions: (txs: Array<TransactionType>, block:
|
|
12
|
+
abstract processTransactions: (txs: Array<TransactionType>, block: BlockInfo) => Promise<boolean>;
|
|
10
13
|
/**
|
|
11
|
-
*
|
|
14
|
+
* Return a unique identifier for this extractor.
|
|
15
|
+
* This ID must be unique across all extractors in the system to prevent conflicts.
|
|
16
|
+
*
|
|
17
|
+
* @returns string - Unique extractor identifier
|
|
12
18
|
*/
|
|
13
19
|
abstract getId: () => string;
|
|
14
20
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
21
|
+
* Fork (rollback) one block and remove all stored information for this block.
|
|
22
|
+
* This is essential for handling blockchain reorganizations where blocks
|
|
23
|
+
* need to be removed from the database.
|
|
24
|
+
*
|
|
25
|
+
* @param hash - Block hash to fork/remove
|
|
17
26
|
*/
|
|
18
27
|
abstract forkBlock: (hash: string) => Promise<void>;
|
|
19
28
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
29
|
+
* Initialize extractor database with historical data created below the initial height.
|
|
30
|
+
* This method is called during extractor setup to populate the database with
|
|
31
|
+
* data that existed before the scanner started monitoring.
|
|
32
|
+
*
|
|
33
|
+
* @param initialBlock - The block from which to start scanning (initial height)
|
|
22
34
|
*/
|
|
23
|
-
abstract
|
|
35
|
+
abstract initializeData: (initialBlock: BlockInfo) => Promise<void>;
|
|
24
36
|
}
|
|
25
37
|
//# sourceMappingURL=abstractExtractor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"abstractExtractor.d.ts","sourceRoot":"","sources":["../lib/abstractExtractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"abstractExtractor.d.ts","sourceRoot":"","sources":["../lib/abstractExtractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAE7D,8BAAsB,iBAAiB,CAAC,eAAe;IACrD;;;;;;;;OAQG;IACH,QAAQ,CAAC,mBAAmB,EAAE,CAC5B,GAAG,EAAE,KAAK,CAAC,eAAe,CAAC,EAC3B,KAAK,EAAE,SAAS,KACb,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtB;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,MAAM,CAAC;IAE7B;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpD;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,EAAE,CAAC,YAAY,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrE"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export class AbstractExtractor {
|
|
2
2
|
}
|
|
3
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJzdHJhY3RFeHRyYWN0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9saWIvYWJzdHJhY3RFeHRyYWN0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsTUFBTSxPQUFnQixpQkFBaUI7Q0F3Q3RDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQmxvY2tJbmZvIH0gZnJvbSAnQHJvc2VuLWJyaWRnZS9zY2FubmVyLWludGVyZmFjZXMnO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RFeHRyYWN0b3I8VHJhbnNhY3Rpb25UeXBlPiB7XG4gIC8qKlxuICAgKiBQcm9jZXNzIGEgbGlzdCBvZiB0cmFuc2FjdGlvbnMgKG9yIG90aGVyIGJsb2NrY2hhaW4gZGF0YSkgaW4gYSBibG9jayBhbmQgc3RvcmUgcmVxdWlyZWQgaW5mb3JtYXRpb24uXG4gICAqIFRoaXMgbWV0aG9kIGlzIHRoZSBjb3JlIG9mIHRoZSBleHRyYWN0aW9uIHByb2Nlc3MgYW5kIHNob3VsZCBiZSBpbXBsZW1lbnRlZCB0byBoYW5kbGVcbiAgICogdGhlIHNwZWNpZmljIGRhdGEgZXh0cmFjdGlvbiBsb2dpYyBmb3IgeW91ciBibG9ja2NoYWluLlxuICAgKlxuICAgKiBAcGFyYW0gdHhzIC0gTGlzdCBvZiB0cmFuc2FjdGlvbnMgb3IgYmxvY2tjaGFpbiBkYXRhIHN0cnVjdHVyZXMgaW4gdGhlIGJsb2NrXG4gICAqIEBwYXJhbSBibG9jayAtIEJsb2NrIGluZm9ybWF0aW9uIGNvbnRhaW5pbmcgbWV0YWRhdGEgYWJvdXQgdGhlIGJsb2NrXG4gICAqIEByZXR1cm5zIFByb21pc2U8Ym9vbGVhbj4gLSB0cnVlIGlmIHRoZSBwcm9jZXNzIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHksIGZhbHNlIG90aGVyd2lzZVxuICAgKi9cbiAgYWJzdHJhY3QgcHJvY2Vzc1RyYW5zYWN0aW9uczogKFxuICAgIHR4czogQXJyYXk8VHJhbnNhY3Rpb25UeXBlPixcbiAgICBibG9jazogQmxvY2tJbmZvLFxuICApID0+IFByb21pc2U8Ym9vbGVhbj47XG5cbiAgLyoqXG4gICAqIFJldHVybiBhIHVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGlzIGV4dHJhY3Rvci5cbiAgICogVGhpcyBJRCBtdXN0IGJlIHVuaXF1ZSBhY3Jvc3MgYWxsIGV4dHJhY3RvcnMgaW4gdGhlIHN5c3RlbSB0byBwcmV2ZW50IGNvbmZsaWN0cy5cbiAgICpcbiAgICogQHJldHVybnMgc3RyaW5nIC0gVW5pcXVlIGV4dHJhY3RvciBpZGVudGlmaWVyXG4gICAqL1xuICBhYnN0cmFjdCBnZXRJZDogKCkgPT4gc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBGb3JrIChyb2xsYmFjaykgb25lIGJsb2NrIGFuZCByZW1vdmUgYWxsIHN0b3JlZCBpbmZvcm1hdGlvbiBmb3IgdGhpcyBibG9jay5cbiAgICogVGhpcyBpcyBlc3NlbnRpYWwgZm9yIGhhbmRsaW5nIGJsb2NrY2hhaW4gcmVvcmdhbml6YXRpb25zIHdoZXJlIGJsb2Nrc1xuICAgKiBuZWVkIHRvIGJlIHJlbW92ZWQgZnJvbSB0aGUgZGF0YWJhc2UuXG4gICAqXG4gICAqIEBwYXJhbSBoYXNoIC0gQmxvY2sgaGFzaCB0byBmb3JrL3JlbW92ZVxuICAgKi9cbiAgYWJzdHJhY3QgZm9ya0Jsb2NrOiAoaGFzaDogc3RyaW5nKSA9PiBQcm9taXNlPHZvaWQ+O1xuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIGV4dHJhY3RvciBkYXRhYmFzZSB3aXRoIGhpc3RvcmljYWwgZGF0YSBjcmVhdGVkIGJlbG93IHRoZSBpbml0aWFsIGhlaWdodC5cbiAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGR1cmluZyBleHRyYWN0b3Igc2V0dXAgdG8gcG9wdWxhdGUgdGhlIGRhdGFiYXNlIHdpdGhcbiAgICogZGF0YSB0aGF0IGV4aXN0ZWQgYmVmb3JlIHRoZSBzY2FubmVyIHN0YXJ0ZWQgbW9uaXRvcmluZy5cbiAgICpcbiAgICogQHBhcmFtIGluaXRpYWxCbG9jayAtIFRoZSBibG9jayBmcm9tIHdoaWNoIHRvIHN0YXJ0IHNjYW5uaW5nIChpbml0aWFsIGhlaWdodClcbiAgICovXG4gIGFic3RyYWN0IGluaXRpYWxpemVEYXRhOiAoaW5pdGlhbEJsb2NrOiBCbG9ja0luZm8pID0+IFByb21pc2U8dm9pZD47XG59XG4iXX0=
|
package/dist/constants.d.ts
CHANGED
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../lib/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,MAAM,CAAC;AAC7B,eAAO,MAAM,aAAa,KAAK,CAAC;AAChC,eAAO,MAAM,aAAa,MAAM,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../lib/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,MAAM,CAAC;AAC7B,eAAO,MAAM,aAAa,KAAK,CAAC;AAChC,eAAO,MAAM,aAAa,MAAM,CAAC;AACjC,eAAO,MAAM,qBAAqB,KAAK,CAAC"}
|
package/dist/constants.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export const API_LIMIT = 100;
|
|
2
2
|
export const RETRIAL_COUNT = 10;
|
|
3
3
|
export const DB_CHUNK_SIZE = 100;
|
|
4
|
-
|
|
4
|
+
export const MAX_PARALLEL_REQUESTS = 10;
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RhbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vbGliL2NvbnN0YW50cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQUMsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDO0FBQzdCLE1BQU0sQ0FBQyxNQUFNLGFBQWEsR0FBRyxFQUFFLENBQUM7QUFDaEMsTUFBTSxDQUFDLE1BQU0sYUFBYSxHQUFHLEdBQUcsQ0FBQztBQUNqQyxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY29uc3QgQVBJX0xJTUlUID0gMTAwO1xuZXhwb3J0IGNvbnN0IFJFVFJJQUxfQ09VTlQgPSAxMDtcbmV4cG9ydCBjb25zdCBEQl9DSFVOS19TSVpFID0gMTAwO1xuZXhwb3J0IGNvbnN0IE1BWF9QQVJBTExFTF9SRVFVRVNUUyA9IDEwO1xuIl19
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { AbstractLogger } from '@rosen-bridge/abstract-logger';
|
|
2
|
+
import { DataSource, EntityTarget, QueryRunner, Repository } from '@rosen-bridge/extended-typeorm';
|
|
3
|
+
import { BlockInfo } from '@rosen-bridge/scanner-interfaces';
|
|
4
|
+
import { AbstractEntityData, EntityInfo } from '../../interfaces';
|
|
5
|
+
import { AbstractErgoEntity } from '../entities/abstractErgoEntity';
|
|
6
|
+
export declare abstract class AbstractErgoAction<ExtractedData extends AbstractEntityData, ExtractorEntity extends AbstractErgoEntity> {
|
|
7
|
+
protected readonly dataSource: DataSource;
|
|
8
|
+
protected readonly repo: EntityTarget<ExtractorEntity>;
|
|
9
|
+
protected readonly logger: AbstractLogger;
|
|
10
|
+
protected readonly repository: Repository<ExtractorEntity>;
|
|
11
|
+
constructor(dataSource: DataSource, repo: EntityTarget<ExtractorEntity>, logger?: AbstractLogger);
|
|
12
|
+
/**
|
|
13
|
+
* create the database entity from extracted data and block information
|
|
14
|
+
*/
|
|
15
|
+
protected abstract createEntity: (data: ExtractedData[], block: BlockInfo, extractor: string) => Array<Omit<ExtractorEntity, 'id'>>;
|
|
16
|
+
/**
|
|
17
|
+
* convert the database entity back to raw data
|
|
18
|
+
*/
|
|
19
|
+
protected abstract convertEntityToData: (entities: ExtractorEntity[]) => ExtractedData[];
|
|
20
|
+
/**
|
|
21
|
+
* insert entities extracted from a block to database
|
|
22
|
+
* @param queryRunner
|
|
23
|
+
* @param entitiesToInsert
|
|
24
|
+
* @param block
|
|
25
|
+
* @param extractor
|
|
26
|
+
*/
|
|
27
|
+
protected insertEntities: (queryRunner: QueryRunner, entitiesToInsert: Array<ExtractedData>, block: BlockInfo, extractor: string) => Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* update an entity in the database
|
|
30
|
+
* @param queryRunner
|
|
31
|
+
* @param updateEntity
|
|
32
|
+
* @param block
|
|
33
|
+
* @param extractor
|
|
34
|
+
*/
|
|
35
|
+
protected updateEntity: (queryRunner: QueryRunner, updatedEntity: ExtractedData, block: BlockInfo, extractor: string) => Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* delete all database records that were created from a specific block
|
|
38
|
+
* @param queryRunner
|
|
39
|
+
* @param extractor
|
|
40
|
+
* @param block
|
|
41
|
+
* @returns
|
|
42
|
+
*/
|
|
43
|
+
protected deleteBlockRecords: (queryRunner: QueryRunner, extractor: string, block: string) => Promise<ExtractedData[]>;
|
|
44
|
+
/**
|
|
45
|
+
* override this method to revert the updates made to entities when a block is deleted
|
|
46
|
+
* e.g., mark boxes as unspent, update related entities, etc.
|
|
47
|
+
* @param queryRunner
|
|
48
|
+
* @param extractor
|
|
49
|
+
* @param block
|
|
50
|
+
* @returns
|
|
51
|
+
*/
|
|
52
|
+
protected revertBlockUpdates: (queryRunner: QueryRunner, // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
53
|
+
extractor: string, // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
54
|
+
block: string) => Promise<ExtractorEntity[]>;
|
|
55
|
+
/**
|
|
56
|
+
* delete extracted data from a specific block
|
|
57
|
+
* if an entity is updated using the data in this block revert the update
|
|
58
|
+
* if an entity is created in this block remove it from database
|
|
59
|
+
* @param block
|
|
60
|
+
* @param extractor
|
|
61
|
+
* @return deleted items and updated entity identifiers
|
|
62
|
+
*/
|
|
63
|
+
deleteBlockData: (block: string, extractor: string) => Promise<{
|
|
64
|
+
deletedData: ExtractedData[];
|
|
65
|
+
updatedData: EntityInfo[];
|
|
66
|
+
}>;
|
|
67
|
+
/**
|
|
68
|
+
* insert all extracted entity data in an atomic transaction
|
|
69
|
+
* update the data if a entity with the same id is already stored in db
|
|
70
|
+
* @param entities
|
|
71
|
+
* @param block
|
|
72
|
+
* @param extractor
|
|
73
|
+
* @return inserted items and updated entity identifiers
|
|
74
|
+
* returns undefined in case of any problem
|
|
75
|
+
*/
|
|
76
|
+
storeEntities: (entities: Array<ExtractedData>, block: BlockInfo, extractor: string) => Promise<boolean>;
|
|
77
|
+
/**
|
|
78
|
+
* remove all existing data for the extractor
|
|
79
|
+
* @param extractorId
|
|
80
|
+
*/
|
|
81
|
+
removeAllData: (extractorId: string) => Promise<void>;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=abstractErgoAction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abstractErgoAction.d.ts","sourceRoot":"","sources":["../../../../lib/ergo/database/actions/abstractErgoAction.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAe,MAAM,+BAA+B,CAAC;AAC5E,OAAO,EACL,UAAU,EACV,YAAY,EAGZ,WAAW,EACX,UAAU,EACX,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAE7D,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEpE,8BAAsB,kBAAkB,CACtC,aAAa,SAAS,kBAAkB,EACxC,eAAe,SAAS,kBAAkB;IAKxC,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,UAAU;IACzC,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC,eAAe,CAAC;IACtD,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,cAAc;IAL3C,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC,eAAe,CAAC,CAAC;gBAGtC,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,YAAY,CAAC,eAAe,CAAC,EACnC,MAAM,GAAE,cAAkC;IAK/D;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,CAC/B,IAAI,EAAE,aAAa,EAAE,EACrB,KAAK,EAAE,SAAS,EAChB,SAAS,EAAE,MAAM,KACd,KAAK,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC,CAAC;IAExC;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,mBAAmB,EAAE,CACtC,QAAQ,EAAE,eAAe,EAAE,KACxB,aAAa,EAAE,CAAC;IAErB;;;;;;OAMG;IACH,SAAS,CAAC,cAAc,GACtB,aAAa,WAAW,EACxB,kBAAkB,KAAK,CAAC,aAAa,CAAC,EACtC,OAAO,SAAS,EAChB,WAAW,MAAM,mBAMjB;IAEF;;;;;;OAMG;IACH,SAAS,CAAC,YAAY,GACpB,aAAa,WAAW,EACxB,eAAe,aAAa,EAC5B,OAAO,SAAS,EAChB,WAAW,MAAM,mBAWjB;IAEF;;;;;;OAMG;IACH,SAAS,CAAC,kBAAkB,GAC1B,aAAa,WAAW,EACxB,WAAW,MAAM,EACjB,OAAO,MAAM,KACZ,OAAO,CAAC,aAAa,EAAE,CAAC,CAazB;IAEF;;;;;;;OAOG;IACH,SAAS,CAAC,kBAAkB,GAC1B,aAAa,WAAW,EAAE,wDAAwD;IAClF,WAAW,MAAM,EAAE,wDAAwD;IAC3E,OAAO,MAAM,KACZ,OAAO,CAAC,eAAe,EAAE,CAAC,CAE3B;IAEF;;;;;;;OAOG;IACH,eAAe,GACb,OAAO,MAAM,EACb,WAAW,MAAM,KAChB,OAAO,CAAC;QAAE,WAAW,EAAE,aAAa,EAAE,CAAC;QAAC,WAAW,EAAE,UAAU,EAAE,CAAA;KAAE,CAAC,CAgCrE;IAEF;;;;;;;;OAQG;IACH,aAAa,GACX,UAAU,KAAK,CAAC,aAAa,CAAC,EAC9B,OAAO,SAAS,EAChB,WAAW,MAAM,KAChB,OAAO,CAAC,OAAO,CAAC,CA4DjB;IAEF;;;OAGG;IACH,aAAa,GAAU,aAAa,MAAM,mBAKxC;CACH"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { difference, pick } from 'lodash-es';
|
|
2
|
+
import { DummyLogger } from '@rosen-bridge/abstract-logger';
|
|
3
|
+
import { In, } from '@rosen-bridge/extended-typeorm';
|
|
4
|
+
import JsonBigInt from '@rosen-bridge/json-bigint';
|
|
5
|
+
export class AbstractErgoAction {
|
|
6
|
+
dataSource;
|
|
7
|
+
repo;
|
|
8
|
+
logger;
|
|
9
|
+
repository;
|
|
10
|
+
constructor(dataSource, repo, logger = new DummyLogger()) {
|
|
11
|
+
this.dataSource = dataSource;
|
|
12
|
+
this.repo = repo;
|
|
13
|
+
this.logger = logger;
|
|
14
|
+
this.repository = this.dataSource.getRepository(repo);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* insert entities extracted from a block to database
|
|
18
|
+
* @param queryRunner
|
|
19
|
+
* @param entitiesToInsert
|
|
20
|
+
* @param block
|
|
21
|
+
* @param extractor
|
|
22
|
+
*/
|
|
23
|
+
insertEntities = async (queryRunner, entitiesToInsert, block, extractor) => {
|
|
24
|
+
const repository = queryRunner.manager.getRepository(this.repo);
|
|
25
|
+
await repository.insert(this.createEntity(entitiesToInsert, block, extractor));
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* update an entity in the database
|
|
29
|
+
* @param queryRunner
|
|
30
|
+
* @param updateEntity
|
|
31
|
+
* @param block
|
|
32
|
+
* @param extractor
|
|
33
|
+
*/
|
|
34
|
+
updateEntity = async (queryRunner, updatedEntity, block, extractor) => {
|
|
35
|
+
const repository = queryRunner.manager.getRepository(this.repo);
|
|
36
|
+
const entity = this.createEntity([updatedEntity], block, extractor)[0];
|
|
37
|
+
await repository.update({
|
|
38
|
+
identifier: entity.identifier,
|
|
39
|
+
extractor: extractor,
|
|
40
|
+
}, entity);
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* delete all database records that were created from a specific block
|
|
44
|
+
* @param queryRunner
|
|
45
|
+
* @param extractor
|
|
46
|
+
* @param block
|
|
47
|
+
* @returns
|
|
48
|
+
*/
|
|
49
|
+
deleteBlockRecords = async (queryRunner, extractor, block) => {
|
|
50
|
+
const repository = queryRunner.manager.getRepository(this.repo);
|
|
51
|
+
const deletedData = await repository.find({
|
|
52
|
+
where: {
|
|
53
|
+
extractor: extractor,
|
|
54
|
+
block: block,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
await repository.delete({
|
|
58
|
+
extractor: extractor,
|
|
59
|
+
block: block,
|
|
60
|
+
});
|
|
61
|
+
return this.convertEntityToData(deletedData);
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* override this method to revert the updates made to entities when a block is deleted
|
|
65
|
+
* e.g., mark boxes as unspent, update related entities, etc.
|
|
66
|
+
* @param queryRunner
|
|
67
|
+
* @param extractor
|
|
68
|
+
* @param block
|
|
69
|
+
* @returns
|
|
70
|
+
*/
|
|
71
|
+
revertBlockUpdates = async (queryRunner, // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
72
|
+
extractor, // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
73
|
+
block) => {
|
|
74
|
+
return [];
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* delete extracted data from a specific block
|
|
78
|
+
* if an entity is updated using the data in this block revert the update
|
|
79
|
+
* if an entity is created in this block remove it from database
|
|
80
|
+
* @param block
|
|
81
|
+
* @param extractor
|
|
82
|
+
* @return deleted items and updated entity identifiers
|
|
83
|
+
*/
|
|
84
|
+
deleteBlockData = async (block, extractor) => {
|
|
85
|
+
this.logger.info(`Deleting data in block ${block} and extractor ${extractor}`);
|
|
86
|
+
const queryRunner = this.dataSource.createQueryRunner();
|
|
87
|
+
await queryRunner.connect();
|
|
88
|
+
await queryRunner.startTransaction();
|
|
89
|
+
try {
|
|
90
|
+
const updatedData = await this.revertBlockUpdates(queryRunner, extractor, block);
|
|
91
|
+
const deletedData = await this.deleteBlockRecords(queryRunner, extractor, block);
|
|
92
|
+
await queryRunner.commitTransaction();
|
|
93
|
+
this.logger.debug(`Deleted data successfully in block ${block} and extractor ${extractor}`);
|
|
94
|
+
return {
|
|
95
|
+
deletedData,
|
|
96
|
+
updatedData: updatedData.map((data) => pick(data, 'identifier')),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
await queryRunner.rollbackTransaction();
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
103
|
+
finally {
|
|
104
|
+
await queryRunner.release();
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* insert all extracted entity data in an atomic transaction
|
|
109
|
+
* update the data if a entity with the same id is already stored in db
|
|
110
|
+
* @param entities
|
|
111
|
+
* @param block
|
|
112
|
+
* @param extractor
|
|
113
|
+
* @return inserted items and updated entity identifiers
|
|
114
|
+
* returns undefined in case of any problem
|
|
115
|
+
*/
|
|
116
|
+
storeEntities = async (entities, block, extractor) => {
|
|
117
|
+
this.logger.debug(`Storing entities in block ${block} and extractor ${extractor}`);
|
|
118
|
+
let entitiesToInsert = [], entitiesToUpdate = [];
|
|
119
|
+
const queryRunner = this.dataSource.createQueryRunner();
|
|
120
|
+
await queryRunner.connect();
|
|
121
|
+
await queryRunner.startTransaction();
|
|
122
|
+
try {
|
|
123
|
+
const repository = queryRunner.manager.getRepository(this.repo);
|
|
124
|
+
const dbEntityIdentifiers = (await repository.findBy({
|
|
125
|
+
identifier: In(entities.map((item) => item.identifier)),
|
|
126
|
+
extractor: extractor,
|
|
127
|
+
})).map((entity) => entity.identifier);
|
|
128
|
+
if (dbEntityIdentifiers.length > 0)
|
|
129
|
+
this.logger.debug(`Found stored entities with same identifier`, dbEntityIdentifiers);
|
|
130
|
+
entitiesToUpdate = entities.filter((entity) => dbEntityIdentifiers.includes(entity.identifier));
|
|
131
|
+
entitiesToInsert = difference(entities, entitiesToUpdate);
|
|
132
|
+
if (entitiesToInsert.length > 0) {
|
|
133
|
+
this.logger.debug(`Inserting ${entitiesToInsert.length} new entities to database`);
|
|
134
|
+
await this.insertEntities(queryRunner, entitiesToInsert, block, extractor);
|
|
135
|
+
}
|
|
136
|
+
if (entitiesToUpdate.length > 0)
|
|
137
|
+
this.logger.info(`Updating entities with following Ids in the database: [${entitiesToUpdate
|
|
138
|
+
.map((entity) => entity.identifier)
|
|
139
|
+
.join(', ')}]`);
|
|
140
|
+
for (const entity of entitiesToUpdate) {
|
|
141
|
+
this.logger.debug(`Updating entities in database [${JsonBigInt.stringify(entity)}]`);
|
|
142
|
+
await this.updateEntity(queryRunner, entity, block, extractor);
|
|
143
|
+
}
|
|
144
|
+
await queryRunner.commitTransaction();
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
catch (e) {
|
|
148
|
+
this.logger.error(`An error occurred during store entities action: ${e}`);
|
|
149
|
+
await queryRunner.rollbackTransaction();
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
finally {
|
|
153
|
+
await queryRunner.release();
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* remove all existing data for the extractor
|
|
158
|
+
* @param extractorId
|
|
159
|
+
*/
|
|
160
|
+
removeAllData = async (extractorId) => {
|
|
161
|
+
this.logger.debug(`Removing all old data for extractor ${extractorId}`);
|
|
162
|
+
await this.repository.delete({
|
|
163
|
+
extractor: extractorId,
|
|
164
|
+
});
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJzdHJhY3RFcmdvQWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vbGliL2VyZ28vZGF0YWJhc2UvYWN0aW9ucy9hYnN0cmFjdEVyZ29BY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFN0MsT0FBTyxFQUFrQixXQUFXLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUM1RSxPQUFPLEVBSUwsRUFBRSxHQUdILE1BQU0sZ0NBQWdDLENBQUM7QUFDeEMsT0FBTyxVQUFVLE1BQU0sMkJBQTJCLENBQUM7QUFNbkQsTUFBTSxPQUFnQixrQkFBa0I7SUFPakI7SUFDQTtJQUNBO0lBTEYsVUFBVSxDQUE4QjtJQUUzRCxZQUNxQixVQUFzQixFQUN0QixJQUFtQyxFQUNuQyxTQUF5QixJQUFJLFdBQVcsRUFBRTtRQUYxQyxlQUFVLEdBQVYsVUFBVSxDQUFZO1FBQ3RCLFNBQUksR0FBSixJQUFJLENBQStCO1FBQ25DLFdBQU0sR0FBTixNQUFNLENBQW9DO1FBRTdELElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQWtCRDs7Ozs7O09BTUc7SUFDTyxjQUFjLEdBQUcsS0FBSyxFQUM5QixXQUF3QixFQUN4QixnQkFBc0MsRUFDdEMsS0FBZ0IsRUFDaEIsU0FBaUIsRUFDakIsRUFBRTtRQUNGLE1BQU0sVUFBVSxHQUFHLFdBQVcsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNoRSxNQUFNLFVBQVUsQ0FBQyxNQUFNLENBQ3JCLElBQUksQ0FBQyxZQUFZLENBQUMsZ0JBQWdCLEVBQUUsS0FBSyxFQUFFLFNBQVMsQ0FBUSxDQUM3RCxDQUFDO0lBQ0osQ0FBQyxDQUFDO0lBRUY7Ozs7OztPQU1HO0lB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Q0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQ3hDLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztnQkFBUyxDQUFDO1lBQ1QsTUFBTSxXQUFXLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDOUIsQ0FBQztJQUNILENBQUMsQ0FBQztJQUVGOzs7T0FHRztJQUNILGFBQWEsR0FBRyxLQUFLLEVBQUUsV0FBbUIsRUFBRSxFQUFFO1FBQzVDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLHVDQUF1QyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1FBQ3hFLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUM7WUFDM0IsU0FBUyxFQUFFLFdBQVc7U0FDYyxDQUFDLENBQUM7SUFDMUMsQ0FBQyxDQUFDO0NBQ0giLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBkaWZmZXJlbmNlLCBwaWNrIH0gZnJvbSAnbG9kYXNoLWVzJztcblxuaW1wb3J0IHsgQWJzdHJhY3RMb2dnZXIsIER1bW15TG9nZ2VyIH0gZnJvbSAnQHJvc2VuLWJyaWRnZS9hYnN0cmFjdC1sb2dnZXInO1xuaW1wb3J0IHtcbiAgRGF0YVNvdXJjZSxcbiAgRW50aXR5VGFyZ2V0LFxuICBGaW5kT3B0aW9uc1doZXJlLFxuICBJbixcbiAgUXVlcnlSdW5uZXIsXG4gIFJlcG9zaXRvcnksXG59IGZyb20gJ0Byb3Nlbi1icmlkZ2UvZXh0ZW5kZWQtdHlwZW9ybSc7XG5pbXBvcnQgSnNvbkJpZ0ludCBmcm9tICdAcm9zZW4tYnJpZGdlL2pzb24tYmlnaW50JztcbmltcG9ydCB7IEJsb2NrSW5mbyB9IGZyb20gJ0Byb3Nlbi1icmlkZ2Uvc2Nhbm5lci1pbnRlcmZhY2VzJztcblxuaW1wb3J0IHsgQWJzdHJhY3RFbnRpdHlEYXRhLCBFbnRpdHlJbmZvIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBBYnN0cmFjdEVyZ29FbnRpdHkgfSBmcm9tICcuLi9lbnRpdGllcy9hYnN0cmFjdEVyZ29FbnRpdHknO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RFcmdvQWN0aW9uPFxuICBFeHRyYWN0ZWREYXRhIGV4dGVuZHMgQWJzdHJhY3RFbnRpdHlEYXRhLFxuICBFeHRyYWN0b3JFbnRpdHkgZXh0ZW5kcyBBYnN0cmFjdEVyZ29FbnRpdHksXG4+IHtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHJlcG9zaXRvcnk6IFJlcG9zaXRvcnk8RXh0cmFjdG9yRW50aXR5PjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgZGF0YVNvdXJjZTogRGF0YVNvdXJjZSxcbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgcmVwbzogRW50aXR5VGFyZ2V0PEV4dHJhY3RvckVudGl0eT4sXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGxvZ2dlcjogQWJzdHJhY3RMb2dnZXIgPSBuZXcgRHVtbXlMb2dnZXIoKSxcbiAgKSB7XG4gICAgdGhpcy5yZXBvc2l0b3J5ID0gdGhpcy5kYXRhU291cmNlLmdldFJlcG9zaXRvcnkocmVwbyk7XG4gIH1cblxuICAvKipcbiAgICogY3JlYXRlIHRoZSBkYXRhYmFzZSBlbnRpdHkgZnJvbSBleHRyYWN0ZWQgZGF0YSBhbmQgYmxvY2sgaW5mb3JtYXRpb25cbiAgICovXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBjcmVhdGVFbnRpdHk6IChcbiAgICBkYXRhOiBFeHRyYWN0ZWREYXRhW10sXG4gICAgYmxvY2s6IEJsb2NrSW5mbyxcbiAgICBleHRyYWN0b3I6IHN0cmluZyxcbiAgKSA9PiBBcnJheTxPbWl0PEV4dHJhY3RvckVudGl0eSwgJ2lkJz4+O1xuXG4gIC8qKlxuICAgKiBjb252ZXJ0IHRoZSBkYXRhYmFzZSBlbnRpdHkgYmFjayB0byByYXcgZGF0YVxuICAgKi9cbiAgcHJvdGVjdGVkIGFic3RyYWN0IGNvbnZlcnRFbnRpdHlUb0RhdGE6IChcbiAgICBlbnRpdGllczogRXh0cmFjdG9yRW50aXR5W10sXG4gICkgPT4gRXh0cmFjdGVkRGF0YVtdO1xuXG4gIC8qKlxuICAgKiBpbnNlcnQgZW50aXRpZXMgZXh0cmFjdGVkIGZyb20gYSBibG9jayB0byBkYXRhYmFzZVxuICAgKiBAcGFyYW0gcXVlcnlSdW5uZXJcbiAgICogQHBhcmFtIGVudGl0aWVzVG9JbnNlcnRcbiAgICogQHBhcmFtIGJsb2NrXG4gICAqIEBwYXJhbSBleHRyYWN0b3JcbiAgICovXG4gIHByb3RlY3RlZCBpbnNlcnRFbnRpdGllcyA9IGFzeW5jIChcbiAgICBxdWVyeVJ1bm5lcjogUXVlcnlSdW5uZXIsXG4gICAgZW50aXRpZXNUb0luc2VydDogQXJyYXk8RXh0cmFjdGVkRGF0YT4sXG4gICAgYmxvY2s6IEJsb2NrSW5mbyxcbiAgICBleHRyYWN0b3I6IHN0cmluZyxcbiAgKSA9PiB7XG4gICAgY29uc3QgcmVwb3NpdG9yeSA9IHF1ZXJ5UnVubmVyLm1hbmFnZXIuZ2V0UmVwb3NpdG9yeSh0aGlzLnJlcG8pO1xuICAgIGF3YWl0IHJlcG9zaXRvcnkuaW5zZXJ0KFxuICAgICAgdGhpcy5jcmVhdGVFbnRpdHkoZW50aXRpZXNUb0luc2VydCwgYmxvY2ssIGV4dHJhY3RvcikgYXMgYW55LCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICApO1xuICB9O1xuXG4gIC8qKlxuICAgKiB1cGRhdGUgYW4gZW50aXR5IGluIHRoZSBkYXRhYmFzZVxuICAgKiBAcGFyYW0gcXVlcnlSdW5uZXJcbiAgICogQHBhcmFtIHVwZGF0ZUVudGl0eVxuICAgKiBAcGFyYW0gYmxvY2tcbiAgICogQHBhcmFtIGV4dHJhY3RvclxuICAgKi9cbiAgcHJvdGVjdGVkIHVwZGF0ZUVudGl0eSA9IGFzeW5jIChcbiAgICBxdWVyeVJ1bm5lcjogUXVlcnlSdW5uZXIsXG4gICAgdXBkYXRlZEVudGl0eTogRXh0cmFjdGVkRGF0YSxcbiAgICBibG9jazogQmxvY2tJbmZvLFxuICAgIGV4dHJhY3Rvcjogc3RyaW5nLFxuICApID0+IHtcbiAgICBjb25zdCByZXBvc2l0b3J5ID0gcXVlcnlSdW5uZXIubWFuYWdlci5nZXRSZXBvc2l0b3J5KHRoaXMucmVwbyk7XG4gICAgY29uc3QgZW50aXR5ID0gdGhpcy5jcmVhdGVFbnRpdHkoW3VwZGF0ZWRFbnRpdHldLCBibG9jaywgZXh0cmFjdG9yKVswXTtcbiAgICBhd2FpdCByZXBvc2l0b3J5LnVwZGF0ZShcbiAgICAgIHtcbiAgICAgICAgaWRlbnRpZmllcjogZW50aXR5LmlkZW50aWZpZXIsXG4gICAgICAgIGV4dHJhY3RvcjogZXh0cmFjdG9yLFxuICAgICAgfSBhcyBGaW5kT3B0aW9uc1doZXJlPEV4dHJhY3RvckVudGl0eT4sXG4gICAgICBlbnRpdHkgYXMgYW55LCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICApO1xuICB9O1xuXG4gIC8qKlxuICAgKiBkZWxldGUgYWxsIGRhdGFiYXNlIHJlY29yZHMgdGhhdCB3ZXJlIGNyZWF0ZWQgZnJvbSBhIHNwZWNpZmljIGJsb2NrXG4gICAqIEBwYXJhbSBxdWVyeVJ1bm5lclxuICAgKiBAcGFyYW0gZXh0cmFjdG9yXG4gICAqIEBwYXJhbSBibG9ja1xuICAgKiBAcmV0dXJuc1xuICAgKi9cbiAgcHJvdGVjdGVkIGRlbGV0ZUJsb2NrUmVjb3JkcyA9IGFzeW5jIChcbiAgICBxdWVyeVJ1bm5lcjogUXVlcnlSdW5uZXIsXG4gICAgZXh0cmFjdG9yOiBzdHJpbmcsXG4gICAgYmxvY2s6IHN0cmluZyxcbiAgKTogUHJvbWlzZTxFeHRyYWN0ZWREYXRhW10+ID0+IHtcbiAgICBjb25zdCByZXBvc2l0b3J5ID0gcXVlcnlSdW5uZXIubWFuYWdlci5nZXRSZXBvc2l0b3J5KHRoaXMucmVwbyk7XG4gICAgY29uc3QgZGVsZXRlZERhdGEgPSBhd2FpdCByZXBvc2l0b3J5LmZpbmQoe1xuICAgICAgd2hlcmU6IHtcbiAgICAgICAgZXh0cmFjdG9yOiBleHRyYWN0b3IsXG4gICAgICAgIGJsb2NrOiBibG9jayxcbiAgICAgIH0gYXMgRmluZE9wdGlvbnNXaGVyZTxFeHRyYWN0b3JFbnRpdHk+LFxuICAgIH0pO1xuICAgIGF3YWl0IHJlcG9zaXRvcnkuZGVsZXRlKHtcbiAgICAgIGV4dHJhY3RvcjogZXh0cmFjdG9yLFxuICAgICAgYmxvY2s6IGJsb2NrLFxuICAgIH0gYXMgdW5rbm93biBhcyBGaW5kT3B0aW9uc1doZXJlPEV4dHJhY3RvckVudGl0eT4pO1xuICAgIHJldHVybiB0aGlzLmNvbnZlcnRFbnRpdHlUb0RhdGEoZGVsZXRlZERhdGEpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBvdmVycmlkZSB0aGlzIG1ldGhvZCB0byByZXZlcnQgdGhlIHVwZGF0ZXMgbWFkZSB0byBlbnRpdGllcyB3aGVuIGEgYmxvY2sgaXMgZGVsZXRlZFxuICAgKiBlLmcuLCBtYXJrIGJveGVzIGFzIHVuc3BlbnQsIHVwZGF0ZSByZWxhdGVkIGVudGl0aWVzLCBldGMuXG4gICAqIEBwYXJhbSBxdWVyeVJ1bm5lclxuICAgKiBAcGFyYW0gZXh0cmFjdG9yXG4gICAqIEBwYXJhbSBibG9ja1xuICAgKiBAcmV0dXJuc1xuICAgKi9cbiAgcHJvdGVjdGVkIHJldmVydEJsb2NrVXBkYXRlcyA9IGFzeW5jIChcbiAgICBxdWVyeVJ1bm5lcjogUXVlcnlSdW5uZXIsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgZXh0cmFjdG9yOiBzdHJpbmcsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgYmxvY2s6IHN0cmluZywgLy8gZXNsaW50LWRpc2FibGUtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgKTogUHJvbWlzZTxFeHRyYWN0b3JFbnRpdHlbXT4gPT4ge1xuICAgIHJldHVybiBbXTtcbiAgfTtcblxuICAvKipcbiAgICogZGVsZXRlIGV4dHJhY3RlZCBkYXRhIGZyb20gYSBzcGVjaWZpYyBibG9ja1xuICAgKiBpZiBhbiBlbnRpdHkgaXMgdXBkYXRlZCB1c2luZyB0aGUgZGF0YSBpbiB0aGlzIGJsb2NrIHJldmVydCB0aGUgdXBkYXRlXG4gICAqIGlmIGFuIGVudGl0eSBpcyBjcmVhdGVkIGluIHRoaXMgYmxvY2sgcmVtb3ZlIGl0IGZyb20gZGF0YWJhc2VcbiAgICogQHBhcmFtIGJsb2NrXG4gICAqIEBwYXJhbSBleHRyYWN0b3JcbiAgICogQHJldHVybiBkZWxldGVkIGl0ZW1zIGFuZCB1cGRhdGVkIGVudGl0eSBpZGVudGlmaWVyc1xuICAgKi9cbiAgZGVsZXRlQmxvY2tEYXRhID0gYXN5bmMgKFxuICAgIGJsb2NrOiBzdHJpbmcsXG4gICAgZXh0cmFjdG9yOiBzdHJpbmcsXG4gICk6IFByb21pc2U8eyBkZWxldGVkRGF0YTogRXh0cmFjdGVkRGF0YVtdOyB1cGRhdGVkRGF0YTogRW50aXR5SW5mb1tdIH0+ID0+IHtcbiAgICB0aGlzLmxvZ2dlci5pbmZvKFxuICAgICAgYERlbGV0aW5nIGRhdGEgaW4gYmxvY2sgJHtibG9ja30gYW5kIGV4dHJhY3RvciAke2V4dHJhY3Rvcn1gLFxuICAgICk7XG4gICAgY29uc3QgcXVlcnlSdW5uZXIgPSB0aGlzLmRhdGFTb3VyY2UuY3JlYXRlUXVlcnlSdW5uZXIoKTtcbiAgICBhd2FpdCBxdWVyeVJ1bm5lci5jb25uZWN0KCk7XG4gICAgYXdhaXQgcXVlcnlSdW5uZXIuc3RhcnRUcmFuc2FjdGlvbigpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB1cGRhdGVkRGF0YSA9IGF3YWl0IHRoaXMucmV2ZXJ0QmxvY2tVcGRhdGVzKFxuICAgICAgICBxdWVyeVJ1bm5lcixcbiAgICAgICAgZXh0cmFjdG9yLFxuICAgICAgICBibG9jayxcbiAgICAgICk7XG4gICAgICBjb25zdCBkZWxldGVkRGF0YSA9IGF3YWl0IHRoaXMuZGVsZXRlQmxvY2tSZWNvcmRzKFxuICAgICAgICBxdWVyeVJ1bm5lcixcbiAgICAgICAgZXh0cmFjdG9yLFxuICAgICAgICBibG9jayxcbiAgICAgICk7XG4gICAgICBhd2FpdCBxdWVyeVJ1bm5lci5jb21taXRUcmFuc2FjdGlvbigpO1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoXG4gICAgICAgIGBEZWxldGVkIGRhdGEgc3VjY2Vzc2Z1bGx5IGluIGJsb2NrICR7YmxvY2t9IGFuZCBleHRyYWN0b3IgJHtleHRyYWN0b3J9YCxcbiAgICAgICk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBkZWxldGVkRGF0YSxcbiAgICAgICAgdXBkYXRlZERhdGE6IHVwZGF0ZWREYXRhLm1hcCgoZGF0YSkgPT4gcGljayhkYXRhLCAnaWRlbnRpZmllcicpKSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGF3YWl0IHF1ZXJ5UnVubmVyLnJvbGxiYWNrVHJhbnNhY3Rpb24oKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBxdWVyeVJ1bm5lci5yZWxlYXNlKCk7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBpbnNlcnQgYWxsIGV4dHJhY3RlZCBlbnRpdHkgZGF0YSBpbiBhbiBhdG9taWMgdHJhbnNhY3Rpb25cbiAgICogdXBkYXRlIHRoZSBkYXRhIGlmIGEgZW50aXR5IHdpdGggdGhlIHNhbWUgaWQgaXMgYWxyZWFkeSBzdG9yZWQgaW4gZGJcbiAgICogQHBhcmFtIGVudGl0aWVzXG4gICAqIEBwYXJhbSBibG9ja1xuICAgKiBAcGFyYW0gZXh0cmFjdG9yXG4gICAqIEByZXR1cm4gaW5zZXJ0ZWQgaXRlbXMgYW5kIHVwZGF0ZWQgZW50aXR5IGlkZW50aWZpZXJzXG4gICAqIHJldHVybnMgdW5kZWZpbmVkIGluIGNhc2Ugb2YgYW55IHByb2JsZW1cbiAgICovXG4gIHN0b3JlRW50aXRpZXMgPSBhc3luYyAoXG4gICAgZW50aXRpZXM6IEFycmF5PEV4dHJhY3RlZERhdGE+LFxuICAgIGJsb2NrOiBCbG9ja0luZm8sXG4gICAgZXh0cmFjdG9yOiBzdHJpbmcsXG4gICk6IFByb21pc2U8Ym9vbGVhbj4gPT4ge1xuICAgIHRoaXMubG9nZ2VyLmRlYnVnKFxuICAgICAgYFN0b3JpbmcgZW50aXRpZXMgaW4gYmxvY2sgJHtibG9ja30gYW5kIGV4dHJhY3RvciAke2V4dHJhY3Rvcn1gLFxuICAgICk7XG4gICAgbGV0IGVudGl0aWVzVG9JbnNlcnQ6IEV4dHJhY3RlZERhdGFbXSA9IFtdLFxuICAgICAgZW50aXRpZXNUb1VwZGF0ZTogRXh0cmFjdGVkRGF0YVtdID0gW107XG4gICAgY29uc3QgcXVlcnlSdW5uZXIgPSB0aGlzLmRhdGFTb3VyY2UuY3JlYXRlUXVlcnlSdW5uZXIoKTtcbiAgICBhd2FpdCBxdWVyeVJ1bm5lci5jb25uZWN0KCk7XG4gICAgYXdhaXQgcXVlcnlSdW5uZXIuc3RhcnRUcmFuc2FjdGlvbigpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXBvc2l0b3J5ID0gcXVlcnlSdW5uZXIubWFuYWdlci5nZXRSZXBvc2l0b3J5KHRoaXMucmVwbyk7XG4gICAgICBjb25zdCBkYkVudGl0eUlkZW50aWZpZXJzID0gKFxuICAgICAgICBhd2FpdCByZXBvc2l0b3J5LmZpbmRCeSh7XG4gICAgICAgICAgaWRlbnRpZmllcjogSW4oZW50aXRpZXMubWFwKChpdGVtKSA9PiBpdGVtLmlkZW50aWZpZXIpKSxcbiAgICAgICAgICBleHRyYWN0b3I6IGV4dHJhY3RvcixcbiAgICAgICAgfSBhcyBGaW5kT3B0aW9uc1doZXJlPEV4dHJhY3RvckVudGl0eT4pXG4gICAgICApLm1hcCgoZW50aXR5KSA9PiBlbnRpdHkuaWRlbnRpZmllcik7XG4gICAgICBpZiAoZGJFbnRpdHlJZGVudGlmaWVycy5sZW5ndGggPiAwKVxuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgICBgRm91bmQgc3RvcmVkIGVudGl0aWVzIHdpdGggc2FtZSBpZGVudGlmaWVyYCxcbiAgICAgICAgICBkYkVudGl0eUlkZW50aWZpZXJzLFxuICAgICAgICApO1xuXG4gICAgICBlbnRpdGllc1RvVXBkYXRlID0gZW50aXRpZXMuZmlsdGVyKChlbnRpdHkpID0+XG4gICAgICAgIGRiRW50aXR5SWRlbnRpZmllcnMuaW5jbHVkZXMoZW50aXR5LmlkZW50aWZpZXIpLFxuICAgICAgKTtcbiAgICAgIGVudGl0aWVzVG9JbnNlcnQgPSBkaWZmZXJlbmNlKGVudGl0aWVzLCBlbnRpdGllc1RvVXBkYXRlKTtcblxuICAgICAgaWYgKGVudGl0aWVzVG9JbnNlcnQubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgICBgSW5zZXJ0aW5nICR7ZW50aXRpZXNUb0luc2VydC5sZW5ndGh9IG5ldyBlbnRpdGllcyB0byBkYXRhYmFzZWAsXG4gICAgICAgICk7XG4gICAgICAgIGF3YWl0IHRoaXMuaW5zZXJ0RW50aXRpZXMoXG4gICAgICAgICAgcXVlcnlSdW5uZXIsXG4gICAgICAgICAgZW50aXRpZXNUb0luc2VydCxcbiAgICAgICAgICBibG9jayxcbiAgICAgICAgICBleHRyYWN0b3IsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoZW50aXRpZXNUb1VwZGF0ZS5sZW5ndGggPiAwKVxuICAgICAgICB0aGlzLmxvZ2dlci5pbmZvKFxuICAgICAgICAgIGBVcGRhdGluZyBlbnRpdGllcyB3aXRoIGZvbGxvd2luZyBJZHMgaW4gdGhlIGRhdGFiYXNlOiBbJHtlbnRpdGllc1RvVXBkYXRlXG4gICAgICAgICAgICAubWFwKChlbnRpdHkpID0+IGVudGl0eS5pZGVudGlmaWVyKVxuICAgICAgICAgICAgLmpvaW4oJywgJyl9XWAsXG4gICAgICAgICk7XG4gICAgICBmb3IgKGNvbnN0IGVudGl0eSBvZiBlbnRpdGllc1RvVXBkYXRlKSB7XG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKFxuICAgICAgICAgIGBVcGRhdGluZyBlbnRpdGllcyBpbiBkYXRhYmFzZSBbJHtKc29uQmlnSW50LnN0cmluZ2lmeShlbnRpdHkpfV1gLFxuICAgICAgICApO1xuICAgICAgICBhd2FpdCB0aGlzLnVwZGF0ZUVudGl0eShxdWVyeVJ1bm5lciwgZW50aXR5LCBibG9jaywgZXh0cmFjdG9yKTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHF1ZXJ5UnVubmVyLmNvbW1pdFRyYW5zYWN0aW9uKCk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLmxvZ2dlci5lcnJvcihgQW4gZXJyb3Igb2NjdXJyZWQgZHVyaW5nIHN0b3JlIGVudGl0aWVzIGFjdGlvbjogJHtlfWApO1xuICAgICAgYXdhaXQgcXVlcnlSdW5uZXIucm9sbGJhY2tUcmFuc2FjdGlvbigpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBxdWVyeVJ1bm5lci5yZWxlYXNlKCk7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiByZW1vdmUgYWxsIGV4aXN0aW5nIGRhdGEgZm9yIHRoZSBleHRyYWN0b3JcbiAgICogQHBhcmFtIGV4dHJhY3RvcklkXG4gICAqL1xuICByZW1vdmVBbGxEYXRhID0gYXN5bmMgKGV4dHJhY3RvcklkOiBzdHJpbmcpID0+IHtcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgUmVtb3ZpbmcgYWxsIG9sZCBkYXRhIGZvciBleHRyYWN0b3IgJHtleHRyYWN0b3JJZH1gKTtcbiAgICBhd2FpdCB0aGlzLnJlcG9zaXRvcnkuZGVsZXRlKHtcbiAgICAgIGV4dHJhY3RvcjogZXh0cmFjdG9ySWQsXG4gICAgfSBhcyBGaW5kT3B0aW9uc1doZXJlPEV4dHJhY3RvckVudGl0eT4pO1xuICB9O1xufVxuIl19
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { AbstractLogger } from '@rosen-bridge/abstract-logger';
|
|
2
|
+
import { DataSource, EntityTarget, QueryRunner } from '@rosen-bridge/extended-typeorm';
|
|
3
|
+
import { BlockInfo } from '@rosen-bridge/scanner-interfaces';
|
|
4
|
+
import { AbstractEntityData, EntityInfo, SpendInfo } from '../../interfaces';
|
|
5
|
+
import { AbstractErgoBoxEntity } from '../entities/abstractErgoBoxEntity';
|
|
6
|
+
import { AbstractErgoAction } from './abstractErgoAction';
|
|
7
|
+
export declare abstract class AbstractErgoBoxAction<ExtractedData extends AbstractEntityData, ExtractorEntity extends AbstractErgoBoxEntity> extends AbstractErgoAction<ExtractedData, ExtractorEntity> {
|
|
8
|
+
constructor(dataSource: DataSource, repo: EntityTarget<ExtractorEntity>, logger?: AbstractLogger);
|
|
9
|
+
/**
|
|
10
|
+
* revert the spending updates when a block is deleted
|
|
11
|
+
* remove spending information of boxes that are spent in the block
|
|
12
|
+
* @param queryRunner
|
|
13
|
+
* @param extractor
|
|
14
|
+
* @param block
|
|
15
|
+
* @returns
|
|
16
|
+
*/
|
|
17
|
+
protected revertBlockUpdates: (queryRunner: QueryRunner, extractor: string, block: string) => Promise<ExtractorEntity[]>;
|
|
18
|
+
/**
|
|
19
|
+
* update spending information of stored boxes
|
|
20
|
+
* chunk spendInfos to prevent large database queries
|
|
21
|
+
* Note: It only updates the spendHeight and spendBlock fields. If updating
|
|
22
|
+
* anything else is required, override this implementation to include the
|
|
23
|
+
* additional fields.
|
|
24
|
+
* @param spendInfos
|
|
25
|
+
* @param block
|
|
26
|
+
* @param extractor
|
|
27
|
+
* @returns spent box ids
|
|
28
|
+
*/
|
|
29
|
+
updateSpendingInfo: (spendInfos: Array<SpendInfo>, block: BlockInfo, extractor: string) => Promise<EntityInfo[]>;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=abstractErgoBoxAction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abstractErgoBoxAction.d.ts","sourceRoot":"","sources":["../../../../lib/ergo/database/actions/abstractErgoBoxAction.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EACL,UAAU,EAGV,YAAY,EAEZ,WAAW,EACZ,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAG7D,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,8BAAsB,qBAAqB,CACzC,aAAa,SAAS,kBAAkB,EACxC,eAAe,SAAS,qBAAqB,CAC7C,SAAQ,kBAAkB,CAAC,aAAa,EAAE,eAAe,CAAC;gBAExD,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,YAAY,CAAC,eAAe,CAAC,EACnC,MAAM,CAAC,EAAE,cAAc;IAKzB;;;;;;;OAOG;IACH,SAAS,CAAC,kBAAkB,GAC1B,aAAa,WAAW,EACxB,WAAW,MAAM,EACjB,OAAO,MAAM,KACZ,OAAO,CAAC,eAAe,EAAE,CAAC,CAoB3B;IAEF;;;;;;;;;;OAUG;IACH,kBAAkB,GAChB,YAAY,KAAK,CAAC,SAAS,CAAC,EAC5B,OAAO,SAAS,EAChB,WAAW,MAAM,KAChB,OAAO,CAAC,UAAU,EAAE,CAAC,CA4BtB;CACH"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { chunk, pick } from 'lodash-es';
|
|
2
|
+
import { In, Not, } from '@rosen-bridge/extended-typeorm';
|
|
3
|
+
import { DB_CHUNK_SIZE } from '../../../constants';
|
|
4
|
+
import { AbstractErgoAction } from './abstractErgoAction';
|
|
5
|
+
export class AbstractErgoBoxAction extends AbstractErgoAction {
|
|
6
|
+
constructor(dataSource, repo, logger) {
|
|
7
|
+
super(dataSource, repo, logger);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* revert the spending updates when a block is deleted
|
|
11
|
+
* remove spending information of boxes that are spent in the block
|
|
12
|
+
* @param queryRunner
|
|
13
|
+
* @param extractor
|
|
14
|
+
* @param block
|
|
15
|
+
* @returns
|
|
16
|
+
*/
|
|
17
|
+
revertBlockUpdates = async (queryRunner, extractor, block) => {
|
|
18
|
+
const repository = queryRunner.manager.getRepository(this.repo);
|
|
19
|
+
const updatedData = await repository.find({
|
|
20
|
+
where: {
|
|
21
|
+
extractor: extractor,
|
|
22
|
+
spendBlock: block,
|
|
23
|
+
block: Not(block),
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
await repository.update({
|
|
27
|
+
spendBlock: block,
|
|
28
|
+
extractor: extractor,
|
|
29
|
+
}, {
|
|
30
|
+
spendBlock: null,
|
|
31
|
+
spendHeight: null,
|
|
32
|
+
});
|
|
33
|
+
return updatedData;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* update spending information of stored boxes
|
|
37
|
+
* chunk spendInfos to prevent large database queries
|
|
38
|
+
* Note: It only updates the spendHeight and spendBlock fields. If updating
|
|
39
|
+
* anything else is required, override this implementation to include the
|
|
40
|
+
* additional fields.
|
|
41
|
+
* @param spendInfos
|
|
42
|
+
* @param block
|
|
43
|
+
* @param extractor
|
|
44
|
+
* @returns spent box ids
|
|
45
|
+
*/
|
|
46
|
+
updateSpendingInfo = async (spendInfos, block, extractor) => {
|
|
47
|
+
const spentData = [];
|
|
48
|
+
const spendInfoChunks = chunk(spendInfos, DB_CHUNK_SIZE);
|
|
49
|
+
for (const spendInfoChunk of spendInfoChunks) {
|
|
50
|
+
const boxIds = spendInfoChunk.map((info) => info.boxId);
|
|
51
|
+
const updateResult = await this.repository.update({
|
|
52
|
+
identifier: In(boxIds),
|
|
53
|
+
extractor: extractor,
|
|
54
|
+
}, {
|
|
55
|
+
spendBlock: block.hash,
|
|
56
|
+
spendHeight: block.height,
|
|
57
|
+
});
|
|
58
|
+
if (updateResult.affected && updateResult.affected > 0) {
|
|
59
|
+
const spentRows = await this.repository.findBy({
|
|
60
|
+
identifier: In(boxIds),
|
|
61
|
+
spendBlock: block.hash,
|
|
62
|
+
});
|
|
63
|
+
spentData.push(...spentRows);
|
|
64
|
+
this.logger.debug(`Spent boxes with boxId ${spentRows.map((row) => row.identifier)} at height ${block.height}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return spentData.map((data) => pick(data, 'identifier'));
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJzdHJhY3RFcmdvQm94QWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vbGliL2VyZ28vZGF0YWJhc2UvYWN0aW9ucy9hYnN0cmFjdEVyZ29Cb3hBY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFHeEMsT0FBTyxFQUVMLEVBQUUsRUFDRixHQUFHLEdBSUosTUFBTSxnQ0FBZ0MsQ0FBQztBQUd4QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFHbkQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFMUQsTUFBTSxPQUFnQixxQkFHcEIsU0FBUSxrQkFBa0Q7SUFDMUQsWUFDRSxVQUFzQixFQUN0QixJQUFtQyxFQUNuQyxNQUF1QjtRQUV2QixLQUFLLENBQUMsVUFBVSxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNPLGtCQUFrQixHQUFHLEtBQUssRUFDbEMsV0FBd0IsRUFDeEIsU0FBaUIsRUFDakIsS0FBYSxFQUNlLEVBQUU7UUFDOUIsTUFBTSxVQUFVLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2hFLE1BQU0sV0FBVyxHQUFHLE1BQU0sVUFBVSxDQUFDLElBQUksQ0FBQztZQUN4QyxLQUFLLEVBQUU7Z0JBQ0wsU0FBUyxFQUFFLFNBQVM7Z0JBQ3BCLFVBQVUsRUFBRSxLQUFLO2dCQUNqQixLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQUssQ0FBQzthQUM4QjtTQUNsRCxDQUFDLENBQUM7UUFDSCxNQUFNLFVBQVUsQ0FBQyxNQUFNLENBQ3JCO1lBQ0UsVUFBVSxFQUFFLEtBQUs7WUFDakIsU0FBUyxFQUFFLFNBQVM7U0FDMkIsRUFDakQ7WUFDRSxVQUFVLEVBQUUsSUFBSTtZQUNoQixXQUFXLEVBQUUsSUFBSTtTQUNYLENBQ1QsQ0FBQztRQUNGLE9BQU8sV0FBMkMsQ0FBQztJQUNyRCxDQUFDLENBQUM7SUFFRjs7Ozs7Ozs7OztPQVVHO0lBQ0gsa0JBQWtCLEdBQUcsS0FBSyxFQUN4QixVQUE0QixFQUM1QixLQUFnQixFQUNoQixTQUFpQixFQUNNLEVBQUU7UUFDekIsTUFBTSxTQUFTLEdBQUcsRUFBRSxDQUFDO1FBQ3JCLE1BQU0sZUFBZSxHQUFHLEtBQUssQ0FBQyxVQUFVLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFDekQsS0FBSyxNQUFNLGNBQWMsSUFBSSxlQUFlLEVBQUUsQ0FBQztZQUM3QyxNQUFNLE1BQU0sR0FBRyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDeEQsTUFBTSxZQUFZLEdBQUcsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FDL0M7Z0JBQ0UsVUFBVSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUM7Z0JBQ3RCLFNBQVMsRUFBRSxTQUFTO2FBQ2dCLEVBQ3RDO2dCQUNFLFVBQVUsRUFBRSxLQUFLLENBQUMsSUFBSTtnQkFDdEIsV0FBVyxFQUFFLEtBQUssQ0FBQyxNQUFNO2FBQ25CLENBQ1QsQ0FBQztZQUVGLElBQUksWUFBWSxDQUFDLFFBQVEsSUFBSSxZQUFZLENBQUMsUUFBUSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUN2RCxNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDO29CQUM3QyxVQUFVLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQztvQkFDdEIsVUFBVSxFQUFFLEtBQUssQ0FBQyxJQUFJO2lCQUNjLENBQUMsQ0FBQztnQkFDeEMsU0FBUyxDQUFDLElBQUksQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDO2dCQUM3QixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FDZiwwQkFBMEIsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxjQUFjLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FDN0YsQ0FBQztZQUNKLENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7SUFDM0QsQ0FBQyxDQUFDO0NBQ0giLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjaHVuaywgcGljayB9IGZyb20gJ2xvZGFzaC1lcyc7XG5cbmltcG9ydCB7IEFic3RyYWN0TG9nZ2VyIH0gZnJvbSAnQHJvc2VuLWJyaWRnZS9hYnN0cmFjdC1sb2dnZXInO1xuaW1wb3J0IHtcbiAgRGF0YVNvdXJjZSxcbiAgSW4sXG4gIE5vdCxcbiAgRW50aXR5VGFyZ2V0LFxuICBGaW5kT3B0aW9uc1doZXJlLFxuICBRdWVyeVJ1bm5lcixcbn0gZnJvbSAnQHJvc2VuLWJyaWRnZS9leHRlbmRlZC10eXBlb3JtJztcbmltcG9ydCB7IEJsb2NrSW5mbyB9IGZyb20gJ0Byb3Nlbi1icmlkZ2Uvc2Nhbm5lci1pbnRlcmZhY2VzJztcblxuaW1wb3J0IHsgREJfQ0hVTktfU0laRSB9IGZyb20gJy4uLy4uLy4uL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBBYnN0cmFjdEVudGl0eURhdGEsIEVudGl0eUluZm8sIFNwZW5kSW5mbyB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgQWJzdHJhY3RFcmdvQm94RW50aXR5IH0gZnJvbSAnLi4vZW50aXRpZXMvYWJzdHJhY3RFcmdvQm94RW50aXR5JztcbmltcG9ydCB7IEFic3RyYWN0RXJnb0FjdGlvbiB9IGZyb20gJy4vYWJzdHJhY3RFcmdvQWN0aW9uJztcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEFic3RyYWN0RXJnb0JveEFjdGlvbjxcbiAgRXh0cmFjdGVkRGF0YSBleHRlbmRzIEFic3RyYWN0RW50aXR5RGF0YSxcbiAgRXh0cmFjdG9yRW50aXR5IGV4dGVuZHMgQWJzdHJhY3RFcmdvQm94RW50aXR5LFxuPiBleHRlbmRzIEFic3RyYWN0RXJnb0FjdGlvbjxFeHRyYWN0ZWREYXRhLCBFeHRyYWN0b3JFbnRpdHk+IHtcbiAgY29uc3RydWN0b3IoXG4gICAgZGF0YVNvdXJjZTogRGF0YVNvdXJjZSxcbiAgICByZXBvOiBFbnRpdHlUYXJnZXQ8RXh0cmFjdG9yRW50aXR5PixcbiAgICBsb2dnZXI/OiBBYnN0cmFjdExvZ2dlcixcbiAgKSB7XG4gICAgc3VwZXIoZGF0YVNvdXJjZSwgcmVwbywgbG9nZ2VyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiByZXZlcnQgdGhlIHNwZW5kaW5nIHVwZGF0ZXMgd2hlbiBhIGJsb2NrIGlzIGRlbGV0ZWRcbiAgICogcmVtb3ZlIHNwZW5kaW5nIGluZm9ybWF0aW9uIG9mIGJveGVzIHRoYXQgYXJlIHNwZW50IGluIHRoZSBibG9ja1xuICAgKiBAcGFyYW0gcXVlcnlSdW5uZXJcbiAgICogQHBhcmFtIGV4dHJhY3RvclxuICAgKiBAcGFyYW0gYmxvY2tcbiAgICogQHJldHVybnNcbiAgICovXG4gIHByb3RlY3RlZCByZXZlcnRCbG9ja1VwZGF0ZXMgPSBhc3luYyAoXG4gICAgcXVlcnlSdW5uZXI6IFF1ZXJ5UnVubmVyLFxuICAgIGV4dHJhY3Rvcjogc3RyaW5nLFxuICAgIGJsb2NrOiBzdHJpbmcsXG4gICk6IFByb21pc2U8RXh0cmFjdG9yRW50aXR5W10+ID0+IHtcbiAgICBjb25zdCByZXBvc2l0b3J5ID0gcXVlcnlSdW5uZXIubWFuYWdlci5nZXRSZXBvc2l0b3J5KHRoaXMucmVwbyk7XG4gICAgY29uc3QgdXBkYXRlZERhdGEgPSBhd2FpdCByZXBvc2l0b3J5LmZpbmQoe1xuICAgICAgd2hlcmU6IHtcbiAgICAgICAgZXh0cmFjdG9yOiBleHRyYWN0b3IsXG4gICAgICAgIHNwZW5kQmxvY2s6IGJsb2NrLFxuICAgICAgICBibG9jazogTm90KGJsb2NrKSxcbiAgICAgIH0gYXMgdW5rbm93biBhcyBGaW5kT3B0aW9uc1doZXJlPEV4dHJhY3RvckVudGl0eT4sXG4gICAgfSk7XG4gICAgYXdhaXQgcmVwb3NpdG9yeS51cGRhdGUoXG4gICAgICB7XG4gICAgICAgIHNwZW5kQmxvY2s6IGJsb2NrLFxuICAgICAgICBleHRyYWN0b3I6IGV4dHJhY3RvcixcbiAgICAgIH0gYXMgdW5rbm93biBhcyBGaW5kT3B0aW9uc1doZXJlPEV4dHJhY3RvckVudGl0eT4sXG4gICAgICB7XG4gICAgICAgIHNwZW5kQmxvY2s6IG51bGwsXG4gICAgICAgIHNwZW5kSGVpZ2h0OiBudWxsLFxuICAgICAgfSBhcyBhbnksIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICk7XG4gICAgcmV0dXJuIHVwZGF0ZWREYXRhIGFzIHVua25vd24gYXMgRXh0cmFjdG9yRW50aXR5W107XG4gIH07XG5cbiAgLyoqXG4gICAqIHVwZGF0ZSBzcGVuZGluZyBpbmZvcm1hdGlvbiBvZiBzdG9yZWQgYm94ZXNcbiAgICogY2h1bmsgc3BlbmRJbmZvcyB0byBwcmV2ZW50IGxhcmdlIGRhdGFiYXNlIHF1ZXJpZXNcbiAgICogTm90ZTogSXQgb25seSB1cGRhdGVzIHRoZSBzcGVuZEhlaWdodCBhbmQgc3BlbmRCbG9jayBmaWVsZHMuIElmIHVwZGF0aW5nXG4gICAqIGFueXRoaW5nIGVsc2UgaXMgcmVxdWlyZWQsIG92ZXJyaWRlIHRoaXMgaW1wbGVtZW50YXRpb24gdG8gaW5jbHVkZSB0aGVcbiAgICogYWRkaXRpb25hbCBmaWVsZHMuXG4gICAqIEBwYXJhbSBzcGVuZEluZm9zXG4gICAqIEBwYXJhbSBibG9ja1xuICAgKiBAcGFyYW0gZXh0cmFjdG9yXG4gICAqIEByZXR1cm5zIHNwZW50IGJveCBpZHNcbiAgICovXG4gIHVwZGF0ZVNwZW5kaW5nSW5mbyA9IGFzeW5jIChcbiAgICBzcGVuZEluZm9zOiBBcnJheTxTcGVuZEluZm8+LFxuICAgIGJsb2NrOiBCbG9ja0luZm8sXG4gICAgZXh0cmFjdG9yOiBzdHJpbmcsXG4gICk6IFByb21pc2U8RW50aXR5SW5mb1tdPiA9PiB7XG4gICAgY29uc3Qgc3BlbnREYXRhID0gW107XG4gICAgY29uc3Qgc3BlbmRJbmZvQ2h1bmtzID0gY2h1bmsoc3BlbmRJbmZvcywgREJfQ0hVTktfU0laRSk7XG4gICAgZm9yIChjb25zdCBzcGVuZEluZm9DaHVuayBvZiBzcGVuZEluZm9DaHVua3MpIHtcbiAgICAgIGNvbnN0IGJveElkcyA9IHNwZW5kSW5mb0NodW5rLm1hcCgoaW5mbykgPT4gaW5mby5ib3hJZCk7XG4gICAgICBjb25zdCB1cGRhdGVSZXN1bHQgPSBhd2FpdCB0aGlzLnJlcG9zaXRvcnkudXBkYXRlKFxuICAgICAgICB7XG4gICAgICAgICAgaWRlbnRpZmllcjogSW4oYm94SWRzKSxcbiAgICAgICAgICBleHRyYWN0b3I6IGV4dHJhY3RvcixcbiAgICAgICAgfSBhcyBGaW5kT3B0aW9uc1doZXJlPEV4dHJhY3RvckVudGl0eT4sXG4gICAgICAgIHtcbiAgICAgICAgICBzcGVuZEJsb2NrOiBibG9jay5oYXNoLFxuICAgICAgICAgIHNwZW5kSGVpZ2h0OiBibG9jay5oZWlnaHQsXG4gICAgICAgIH0gYXMgYW55LCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgICk7XG5cbiAgICAgIGlmICh1cGRhdGVSZXN1bHQuYWZmZWN0ZWQgJiYgdXBkYXRlUmVzdWx0LmFmZmVjdGVkID4gMCkge1xuICAgICAgICBjb25zdCBzcGVudFJvd3MgPSBhd2FpdCB0aGlzLnJlcG9zaXRvcnkuZmluZEJ5KHtcbiAgICAgICAgICBpZGVudGlmaWVyOiBJbihib3hJZHMpLFxuICAgICAgICAgIHNwZW5kQmxvY2s6IGJsb2NrLmhhc2gsXG4gICAgICAgIH0gYXMgRmluZE9wdGlvbnNXaGVyZTxFeHRyYWN0b3JFbnRpdHk+KTtcbiAgICAgICAgc3BlbnREYXRhLnB1c2goLi4uc3BlbnRSb3dzKTtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoXG4gICAgICAgICAgYFNwZW50IGJveGVzIHdpdGggYm94SWQgJHtzcGVudFJvd3MubWFwKChyb3cpID0+IHJvdy5pZGVudGlmaWVyKX0gYXQgaGVpZ2h0ICR7YmxvY2suaGVpZ2h0fWAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzcGVudERhdGEubWFwKChkYXRhKSA9PiBwaWNrKGRhdGEsICdpZGVudGlmaWVyJykpO1xuICB9O1xufVxuIl19
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { AbstractErgoEntity } from './abstractErgoEntity';
|
|
2
|
+
/**
|
|
3
|
+
* Box entity for UTXO-based data extraction.
|
|
4
|
+
*
|
|
5
|
+
* This entity extends the base AbstractErgoEntity with box-specific fields
|
|
6
|
+
* for tracking UTXO spending states.
|
|
7
|
+
*/
|
|
8
|
+
export declare abstract class AbstractErgoBoxEntity extends AbstractErgoEntity {
|
|
9
|
+
/**
|
|
10
|
+
* Block hash where this box was spent (null if unspent).
|
|
11
|
+
*/
|
|
12
|
+
spendBlock?: string | null;
|
|
13
|
+
/**
|
|
14
|
+
* Block height where this box was spent (null if unspent).
|
|
15
|
+
*/
|
|
16
|
+
spendHeight?: number | null;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=abstractErgoBoxEntity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abstractErgoBoxEntity.d.ts","sourceRoot":"","sources":["../../../../lib/ergo/database/entities/abstractErgoBoxEntity.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;;;;GAKG;AACH,8BAAsB,qBAAsB,SAAQ,kBAAkB;IACpE;;OAEG;IAEH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3B;;OAEG;IAEH,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { Column } from '@rosen-bridge/extended-typeorm';
|
|
11
|
+
import { AbstractErgoEntity } from './abstractErgoEntity';
|
|
12
|
+
/**
|
|
13
|
+
* Box entity for UTXO-based data extraction.
|
|
14
|
+
*
|
|
15
|
+
* This entity extends the base AbstractErgoEntity with box-specific fields
|
|
16
|
+
* for tracking UTXO spending states.
|
|
17
|
+
*/
|
|
18
|
+
export class AbstractErgoBoxEntity extends AbstractErgoEntity {
|
|
19
|
+
/**
|
|
20
|
+
* Block hash where this box was spent (null if unspent).
|
|
21
|
+
*/
|
|
22
|
+
spendBlock;
|
|
23
|
+
/**
|
|
24
|
+
* Block height where this box was spent (null if unspent).
|
|
25
|
+
*/
|
|
26
|
+
spendHeight;
|
|
27
|
+
}
|
|
28
|
+
__decorate([
|
|
29
|
+
Column({ nullable: true, type: 'varchar' }),
|
|
30
|
+
__metadata("design:type", Object)
|
|
31
|
+
], AbstractErgoBoxEntity.prototype, "spendBlock", void 0);
|
|
32
|
+
__decorate([
|
|
33
|
+
Column({ nullable: true, type: 'int' }),
|
|
34
|
+
__metadata("design:type", Object)
|
|
35
|
+
], AbstractErgoBoxEntity.prototype, "spendHeight", void 0);
|
|
36
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJzdHJhY3RFcmdvQm94RW50aXR5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vbGliL2VyZ28vZGF0YWJhc2UvZW50aXRpZXMvYWJzdHJhY3RFcmdvQm94RW50aXR5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUV4RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUUxRDs7Ozs7R0FLRztBQUNILE1BQU0sT0FBZ0IscUJBQXNCLFNBQVEsa0JBQWtCO0lBQ3BFOztPQUVHO0lBRUgsVUFBVSxDQUFpQjtJQUUzQjs7T0FFRztJQUVILFdBQVcsQ0FBaUI7Q0FDN0I7QUFQQztJQURDLE1BQU0sQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxDQUFDOzt5REFDakI7QUFNM0I7SUFEQyxNQUFNLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsQ0FBQzs7MERBQ1oiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb2x1bW4gfSBmcm9tICdAcm9zZW4tYnJpZGdlL2V4dGVuZGVkLXR5cGVvcm0nO1xuXG5pbXBvcnQgeyBBYnN0cmFjdEVyZ29FbnRpdHkgfSBmcm9tICcuL2Fic3RyYWN0RXJnb0VudGl0eSc7XG5cbi8qKlxuICogQm94IGVudGl0eSBmb3IgVVRYTy1iYXNlZCBkYXRhIGV4dHJhY3Rpb24uXG4gKlxuICogVGhpcyBlbnRpdHkgZXh0ZW5kcyB0aGUgYmFzZSBBYnN0cmFjdEVyZ29FbnRpdHkgd2l0aCBib3gtc3BlY2lmaWMgZmllbGRzXG4gKiBmb3IgdHJhY2tpbmcgVVRYTyBzcGVuZGluZyBzdGF0ZXMuXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdEVyZ29Cb3hFbnRpdHkgZXh0ZW5kcyBBYnN0cmFjdEVyZ29FbnRpdHkge1xuICAvKipcbiAgICogQmxvY2sgaGFzaCB3aGVyZSB0aGlzIGJveCB3YXMgc3BlbnQgKG51bGwgaWYgdW5zcGVudCkuXG4gICAqL1xuICBAQ29sdW1uKHsgbnVsbGFibGU6IHRydWUsIHR5cGU6ICd2YXJjaGFyJyB9KVxuICBzcGVuZEJsb2NrPzogc3RyaW5nIHwgbnVsbDtcblxuICAvKipcbiAgICogQmxvY2sgaGVpZ2h0IHdoZXJlIHRoaXMgYm94IHdhcyBzcGVudCAobnVsbCBpZiB1bnNwZW50KS5cbiAgICovXG4gIEBDb2x1bW4oeyBudWxsYWJsZTogdHJ1ZSwgdHlwZTogJ2ludCcgfSlcbiAgc3BlbmRIZWlnaHQ/OiBudW1iZXIgfCBudWxsO1xufVxuIl19
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abstract base entity for storing extracted blockchain data.
|
|
3
|
+
*
|
|
4
|
+
* This entity serves as the foundation for all extracted data storage,
|
|
5
|
+
* supporting both box-based and transaction-based extraction patterns.
|
|
6
|
+
* The identifier field can represent different types of blockchain data:
|
|
7
|
+
* - For box-based extractors: boxId (UTXO identifier)
|
|
8
|
+
* - For transaction-based extractors: txId (transaction identifier)
|
|
9
|
+
* - For general extractors: any unique blockchain data identifier
|
|
10
|
+
*/
|
|
11
|
+
export declare abstract class AbstractErgoEntity {
|
|
12
|
+
id: number;
|
|
13
|
+
block: string;
|
|
14
|
+
height: number;
|
|
15
|
+
extractor: string;
|
|
16
|
+
/**
|
|
17
|
+
* Unique identifier for the entity in the blockchain.
|
|
18
|
+
* This can be:
|
|
19
|
+
* - boxId for UTXO-based data (box extractors)
|
|
20
|
+
* - txId for transaction-based data (general extractors)
|
|
21
|
+
* - Any unique blockchain data identifier for custom extractors
|
|
22
|
+
*/
|
|
23
|
+
identifier: string;
|
|
24
|
+
serialized: string;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=abstractErgoEntity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abstractErgoEntity.d.ts","sourceRoot":"","sources":["../../../../lib/ergo/database/entities/abstractErgoEntity.ts"],"names":[],"mappings":"AAMA;;;;;;;;;GASG;AACH,8BACsB,kBAAkB;IAEtC,EAAE,EAAE,MAAM,CAAC;IAGX,KAAK,EAAE,MAAM,CAAC;IAGd,MAAM,EAAE,MAAM,CAAC;IAGf,SAAS,EAAE,MAAM,CAAC;IAElB;;;;;;OAMG;IAEH,UAAU,EAAE,MAAM,CAAC;IAGnB,UAAU,EAAE,MAAM,CAAC;CACpB"}
|