@lido-nestjs/registry 1.1.2 → 1.3.0
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/dist/main/abstract-registry.d.ts +5 -1
- package/dist/main/abstract-registry.js +55 -22
- package/dist/storage/key.repository.d.ts +1 -1
- package/dist/storage/key.repository.js +2 -2
- package/dist/storage/key.storage.js +4 -1
- package/dist/storage/meta.repository.d.ts +1 -1
- package/dist/storage/meta.repository.js +2 -2
- package/dist/storage/operator.repository.d.ts +1 -1
- package/dist/storage/operator.repository.js +2 -2
- package/dist/storage/operator.storage.js +4 -1
- package/package.json +6 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { LoggerService } from '@nestjs/common';
|
|
3
3
|
import { Registry } from '@lido-nestjs/contracts';
|
|
4
|
-
import { EntityManager } from '@mikro-orm/
|
|
4
|
+
import { EntityManager } from '@mikro-orm/knex';
|
|
5
5
|
import EventEmitter from 'events';
|
|
6
6
|
import { CronJob } from 'cron';
|
|
7
7
|
import { RegistryMetaFetchService } from '../fetch/meta.fetch';
|
|
@@ -47,6 +47,10 @@ export declare abstract class AbstractRegistryService {
|
|
|
47
47
|
getMetaDataFromStorage(): Promise<RegistryMeta | null>;
|
|
48
48
|
/** returns the latest operators data from the db */
|
|
49
49
|
getOperatorsFromStorage(): Promise<RegistryOperator[]>;
|
|
50
|
+
/** returns all the keys from storage */
|
|
51
|
+
getOperatorsKeysFromStorage(): Promise<RegistryKey[]>;
|
|
52
|
+
/** saves all the data to the db */
|
|
53
|
+
save(updatedKeys: RegistryKey[], currentOperators: RegistryOperator[], currMeta: RegistryMeta): Promise<void>;
|
|
50
54
|
/** clears the db */
|
|
51
55
|
clear(): Promise<void>;
|
|
52
56
|
}
|
|
@@ -5,7 +5,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
var tslib = require('tslib');
|
|
6
6
|
var common = require('@nestjs/common');
|
|
7
7
|
var contracts = require('@lido-nestjs/contracts');
|
|
8
|
-
var
|
|
8
|
+
var knex = require('@mikro-orm/knex');
|
|
9
9
|
var logger = require('@lido-nestjs/logger');
|
|
10
10
|
var decorators = require('@lido-nestjs/decorators');
|
|
11
11
|
var EventEmitter = require('events');
|
|
@@ -22,6 +22,7 @@ var operator_entity = require('../storage/operator.entity.js');
|
|
|
22
22
|
var meta_utils = require('../utils/meta.utils.js');
|
|
23
23
|
var operator_utils = require('../utils/operator.utils.js');
|
|
24
24
|
var constants = require('./constants.js');
|
|
25
|
+
var utils = require('@lido-nestjs/utils');
|
|
25
26
|
|
|
26
27
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
27
28
|
|
|
@@ -40,7 +41,7 @@ exports.AbstractRegistryService = class AbstractRegistryService {
|
|
|
40
41
|
this.entityManager = entityManager;
|
|
41
42
|
this.options = options;
|
|
42
43
|
this.eventEmitter = new EventEmitter__default["default"]();
|
|
43
|
-
this.cronJob = new cron.CronJob((options === null || options === void 0 ? void 0 : options.subscribeInterval) || '*/10 * * * * *', this.cronHandler);
|
|
44
|
+
this.cronJob = new cron.CronJob((options === null || options === void 0 ? void 0 : options.subscribeInterval) || '*/10 * * * * *', () => this.cronHandler());
|
|
44
45
|
}
|
|
45
46
|
async cronHandler() {
|
|
46
47
|
try {
|
|
@@ -86,9 +87,8 @@ exports.AbstractRegistryService = class AbstractRegistryService {
|
|
|
86
87
|
if (isSameContractState) {
|
|
87
88
|
(_c = (_b = this.logger).debug) === null || _c === void 0 ? void 0 : _c.call(_b, 'Same state, no data update required', { currMeta });
|
|
88
89
|
await this.entityManager.transactional(async (entityManager) => {
|
|
89
|
-
entityManager.nativeDelete(meta_entity.RegistryMeta, {});
|
|
90
|
-
|
|
91
|
-
entityManager.persist(meta);
|
|
90
|
+
await entityManager.nativeDelete(meta_entity.RegistryMeta, {});
|
|
91
|
+
await entityManager.persist(new meta_entity.RegistryMeta(currMeta));
|
|
92
92
|
});
|
|
93
93
|
(_e = (_d = this.logger).debug) === null || _e === void 0 ? void 0 : _e.call(_d, 'Updated metadata in the DB', { currMeta });
|
|
94
94
|
return;
|
|
@@ -104,20 +104,7 @@ exports.AbstractRegistryService = class AbstractRegistryService {
|
|
|
104
104
|
this.logger.log('Fetched updated keys', {
|
|
105
105
|
updatedKeys: updatedKeys.length,
|
|
106
106
|
});
|
|
107
|
-
|
|
108
|
-
await this.entityManager.transactional(async (entityManager) => {
|
|
109
|
-
updatedKeys.forEach(async (operatorKey) => {
|
|
110
|
-
const instance = new key_entity.RegistryKey(operatorKey);
|
|
111
|
-
entityManager.persist(instance);
|
|
112
|
-
});
|
|
113
|
-
currentOperators.forEach(async (operator) => {
|
|
114
|
-
const instance = new operator_entity.RegistryOperator(operator);
|
|
115
|
-
entityManager.persist(instance);
|
|
116
|
-
});
|
|
117
|
-
entityManager.nativeDelete(meta_entity.RegistryMeta, {});
|
|
118
|
-
const meta = new meta_entity.RegistryMeta(currMeta);
|
|
119
|
-
entityManager.persist(meta);
|
|
120
|
-
});
|
|
107
|
+
await this.save(updatedKeys, currentOperators, currMeta);
|
|
121
108
|
this.logger.log('Saved data to the DB', {
|
|
122
109
|
operators: currentOperators.length,
|
|
123
110
|
updatedKeys: updatedKeys.length,
|
|
@@ -161,8 +148,12 @@ exports.AbstractRegistryService = class AbstractRegistryService {
|
|
|
161
148
|
const unchangedKeysMaxIndex = isSameOperator
|
|
162
149
|
? prevOperator.usedSigningKeys
|
|
163
150
|
: 0;
|
|
164
|
-
|
|
151
|
+
// get the right border up to which the keys should be updated
|
|
152
|
+
// it's different for different scenarios
|
|
165
153
|
const toIndex = this.getToIndex(currOperator);
|
|
154
|
+
// fromIndex may become larger than toIndex if used keys are deleted
|
|
155
|
+
// this should not happen in mainnet, but sometimes keys can be deleted in testnet by modification of the contract
|
|
156
|
+
const fromIndex = unchangedKeysMaxIndex <= toIndex ? unchangedKeysMaxIndex : 0;
|
|
166
157
|
const operatorIndex = currOperator.index;
|
|
167
158
|
const overrides = { blockTag: { blockHash } };
|
|
168
159
|
const result = await this.keyFetch.fetch(operatorIndex, fromIndex, toIndex, overrides);
|
|
@@ -174,7 +165,7 @@ exports.AbstractRegistryService = class AbstractRegistryService {
|
|
|
174
165
|
});
|
|
175
166
|
return result;
|
|
176
167
|
}));
|
|
177
|
-
return keysByOperator.flat();
|
|
168
|
+
return keysByOperator.flat().filter((key) => key);
|
|
178
169
|
}
|
|
179
170
|
/** storage */
|
|
180
171
|
/** returns the latest meta data from the db */
|
|
@@ -185,6 +176,48 @@ exports.AbstractRegistryService = class AbstractRegistryService {
|
|
|
185
176
|
async getOperatorsFromStorage() {
|
|
186
177
|
return await this.operatorStorage.findAll();
|
|
187
178
|
}
|
|
179
|
+
/** returns all the keys from storage */
|
|
180
|
+
async getOperatorsKeysFromStorage() {
|
|
181
|
+
return await this.keyStorage.findAll();
|
|
182
|
+
}
|
|
183
|
+
/** saves all the data to the db */
|
|
184
|
+
async save(updatedKeys, currentOperators, currMeta) {
|
|
185
|
+
// save all data in a transaction
|
|
186
|
+
await this.entityManager.transactional(async (entityManager) => {
|
|
187
|
+
await Promise.all(
|
|
188
|
+
// remove all keys from the database that are greater than the total number of keys
|
|
189
|
+
// it's needed to clear the list in db when removing keys from the contract
|
|
190
|
+
currentOperators.map(async (operator) => {
|
|
191
|
+
await entityManager.nativeDelete(key_entity.RegistryKey, {
|
|
192
|
+
index: { $gte: operator.totalSigningKeys },
|
|
193
|
+
operatorIndex: operator.index,
|
|
194
|
+
});
|
|
195
|
+
}));
|
|
196
|
+
await Promise.all(
|
|
197
|
+
// 500 — SQLite limit in insert operation
|
|
198
|
+
utils.chunk(updatedKeys, 499).map(async (keysChunk) => {
|
|
199
|
+
await entityManager
|
|
200
|
+
.createQueryBuilder(key_entity.RegistryKey)
|
|
201
|
+
.insert(keysChunk)
|
|
202
|
+
.onConflict(['index', 'operator_index'])
|
|
203
|
+
.merge()
|
|
204
|
+
.execute();
|
|
205
|
+
}));
|
|
206
|
+
await Promise.all(
|
|
207
|
+
// 500 — SQLite limit in insert operation
|
|
208
|
+
utils.chunk(currentOperators, 499).map(async (operatorsChunk) => {
|
|
209
|
+
await entityManager
|
|
210
|
+
.createQueryBuilder(operator_entity.RegistryOperator)
|
|
211
|
+
.insert(operatorsChunk)
|
|
212
|
+
.onConflict('index')
|
|
213
|
+
.merge()
|
|
214
|
+
.execute();
|
|
215
|
+
}));
|
|
216
|
+
// replace metadata with new one
|
|
217
|
+
await entityManager.nativeDelete(meta_entity.RegistryMeta, {});
|
|
218
|
+
await entityManager.persist(new meta_entity.RegistryMeta(currMeta));
|
|
219
|
+
});
|
|
220
|
+
}
|
|
188
221
|
/** clears the db */
|
|
189
222
|
async clear() {
|
|
190
223
|
await this.entityManager.transactional(async (entityManager) => {
|
|
@@ -212,5 +245,5 @@ exports.AbstractRegistryService = tslib.__decorate([
|
|
|
212
245
|
key_storage.RegistryKeyStorageService,
|
|
213
246
|
operator_fetch.RegistryOperatorFetchService,
|
|
214
247
|
operator_storage.RegistryOperatorStorageService,
|
|
215
|
-
|
|
248
|
+
knex.EntityManager, Object])
|
|
216
249
|
], exports.AbstractRegistryService);
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var knex = require('@mikro-orm/knex');
|
|
6
6
|
|
|
7
|
-
class RegistryKeyRepository extends
|
|
7
|
+
class RegistryKeyRepository extends knex.EntityRepository {
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
exports.RegistryKeyRepository = RegistryKeyRepository;
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var tslib = require('tslib');
|
|
6
|
+
var core = require('@mikro-orm/core');
|
|
6
7
|
var common = require('@nestjs/common');
|
|
7
8
|
var key_entity = require('./key.entity.js');
|
|
8
9
|
var key_repository = require('./key.repository.js');
|
|
@@ -13,7 +14,9 @@ exports.RegistryKeyStorageService = class RegistryKeyStorageService {
|
|
|
13
14
|
}
|
|
14
15
|
/** find all keys */
|
|
15
16
|
async findAll() {
|
|
16
|
-
return await this.repository.findAll(
|
|
17
|
+
return await this.repository.findAll({
|
|
18
|
+
orderBy: [{ operatorIndex: core.QueryOrder.ASC }, { index: core.QueryOrder.ASC }],
|
|
19
|
+
});
|
|
17
20
|
}
|
|
18
21
|
/** find used keys */
|
|
19
22
|
async findUsed() {
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var knex = require('@mikro-orm/knex');
|
|
6
6
|
|
|
7
|
-
class RegistryMetaRepository extends
|
|
7
|
+
class RegistryMetaRepository extends knex.EntityRepository {
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
exports.RegistryMetaRepository = RegistryMetaRepository;
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var knex = require('@mikro-orm/knex');
|
|
6
6
|
|
|
7
|
-
class RegistryOperatorRepository extends
|
|
7
|
+
class RegistryOperatorRepository extends knex.EntityRepository {
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
exports.RegistryOperatorRepository = RegistryOperatorRepository;
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var tslib = require('tslib');
|
|
6
|
+
var core = require('@mikro-orm/core');
|
|
6
7
|
var common = require('@nestjs/common');
|
|
7
8
|
var operator_entity = require('./operator.entity.js');
|
|
8
9
|
var operator_repository = require('./operator.repository.js');
|
|
@@ -13,7 +14,9 @@ exports.RegistryOperatorStorageService = class RegistryOperatorStorageService {
|
|
|
13
14
|
}
|
|
14
15
|
/** find all operators */
|
|
15
16
|
async findAll() {
|
|
16
|
-
return await this.repository.findAll(
|
|
17
|
+
return await this.repository.findAll({
|
|
18
|
+
orderBy: [{ index: core.QueryOrder.ASC }],
|
|
19
|
+
});
|
|
17
20
|
}
|
|
18
21
|
/** find operator by index */
|
|
19
22
|
async findOneByIndex(operatorIndex) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lido-nestjs/registry",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,12 +30,13 @@
|
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@lido-nestjs/contracts": "2.1.0",
|
|
32
32
|
"@lido-nestjs/decorators": "1.0.0",
|
|
33
|
-
"@lido-nestjs/logger": "1.
|
|
34
|
-
"@lido-nestjs/utils": "1.
|
|
33
|
+
"@lido-nestjs/logger": "1.2.0",
|
|
34
|
+
"@lido-nestjs/utils": "1.2.0",
|
|
35
35
|
"cron": "^2.0.0"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@mikro-orm/core": "^5.2.0",
|
|
39
|
+
"@mikro-orm/knex": "^5.2.0",
|
|
39
40
|
"@mikro-orm/nestjs": "^5.0.2",
|
|
40
41
|
"@nestjs/common": "^8.2.5",
|
|
41
42
|
"@nestjs/core": "^8.2.5",
|
|
@@ -44,8 +45,9 @@
|
|
|
44
45
|
"tslib": "^2.3.1"
|
|
45
46
|
},
|
|
46
47
|
"devDependencies": {
|
|
47
|
-
"@lido-nestjs/execution": "1.7.
|
|
48
|
+
"@lido-nestjs/execution": "1.7.1",
|
|
48
49
|
"@mikro-orm/core": "^5.2.0",
|
|
50
|
+
"@mikro-orm/knex": "^5.2.0",
|
|
49
51
|
"@mikro-orm/nestjs": "^5.0.2",
|
|
50
52
|
"@mikro-orm/sqlite": "^5.2.0",
|
|
51
53
|
"@nestjs/common": "^8.2.5",
|