@lido-nestjs/registry 1.1.3 → 1.4.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.
@@ -47,7 +47,9 @@ 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 */
50
51
  getOperatorsKeysFromStorage(): Promise<RegistryKey[]>;
52
+ /** saves all the data to the db */
51
53
  save(updatedKeys: RegistryKey[], currentOperators: RegistryOperator[], currMeta: RegistryMeta): Promise<void>;
52
54
  /** clears the db */
53
55
  clear(): Promise<void>;
@@ -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 {
@@ -147,8 +148,12 @@ exports.AbstractRegistryService = class AbstractRegistryService {
147
148
  const unchangedKeysMaxIndex = isSameOperator
148
149
  ? prevOperator.usedSigningKeys
149
150
  : 0;
150
- const fromIndex = unchangedKeysMaxIndex;
151
+ // get the right border up to which the keys should be updated
152
+ // it's different for different scenarios
151
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;
152
157
  const operatorIndex = currOperator.index;
153
158
  const overrides = { blockTag: { blockHash } };
154
159
  const result = await this.keyFetch.fetch(operatorIndex, fromIndex, toIndex, overrides);
@@ -160,7 +165,7 @@ exports.AbstractRegistryService = class AbstractRegistryService {
160
165
  });
161
166
  return result;
162
167
  }));
163
- return keysByOperator.flat();
168
+ return keysByOperator.flat().filter((key) => key);
164
169
  }
165
170
  /** storage */
166
171
  /** returns the latest meta data from the db */
@@ -171,24 +176,44 @@ exports.AbstractRegistryService = class AbstractRegistryService {
171
176
  async getOperatorsFromStorage() {
172
177
  return await this.operatorStorage.findAll();
173
178
  }
179
+ /** returns all the keys from storage */
174
180
  async getOperatorsKeysFromStorage() {
175
181
  return await this.keyStorage.findAll();
176
182
  }
183
+ /** saves all the data to the db */
177
184
  async save(updatedKeys, currentOperators, currMeta) {
178
185
  // save all data in a transaction
179
186
  await this.entityManager.transactional(async (entityManager) => {
180
- await entityManager
181
- .createQueryBuilder(key_entity.RegistryKey)
182
- .insert(updatedKeys)
183
- .onConflict(['index', 'operator_index'])
184
- .merge()
185
- .execute();
186
- await entityManager
187
- .createQueryBuilder(operator_entity.RegistryOperator)
188
- .insert(currentOperators)
189
- .onConflict('index')
190
- .merge()
191
- .execute();
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
192
217
  await entityManager.nativeDelete(meta_entity.RegistryMeta, {});
193
218
  await entityManager.persist(new meta_entity.RegistryMeta(currMeta));
194
219
  });
@@ -1,8 +1,11 @@
1
+ import { FilterQuery, FindOptions } from '@mikro-orm/core';
1
2
  import { RegistryKey } from './key.entity';
2
3
  import { RegistryKeyRepository } from './key.repository';
3
4
  export declare class RegistryKeyStorageService {
4
5
  private readonly repository;
5
6
  constructor(repository: RegistryKeyRepository);
7
+ /** find keys */
8
+ find<P extends string = never>(where: FilterQuery<RegistryKey>, options?: FindOptions<RegistryKey, P>): Promise<RegistryKey[]>;
6
9
  /** find all keys */
7
10
  findAll(): Promise<RegistryKey[]>;
8
11
  /** find used keys */
@@ -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');
@@ -11,9 +12,15 @@ exports.RegistryKeyStorageService = class RegistryKeyStorageService {
11
12
  constructor(repository) {
12
13
  this.repository = repository;
13
14
  }
15
+ /** find keys */
16
+ async find(where, options) {
17
+ return await this.repository.find(where, options);
18
+ }
14
19
  /** find all keys */
15
20
  async findAll() {
16
- return await this.repository.findAll();
21
+ return await this.repository.findAll({
22
+ orderBy: [{ operatorIndex: core.QueryOrder.ASC }, { index: core.QueryOrder.ASC }],
23
+ });
17
24
  }
18
25
  /** find used keys */
19
26
  async findUsed() {
@@ -1,8 +1,11 @@
1
+ import { FilterQuery, FindOptions } from '@mikro-orm/core';
1
2
  import { RegistryOperator } from './operator.entity';
2
3
  import { RegistryOperatorRepository } from './operator.repository';
3
4
  export declare class RegistryOperatorStorageService {
4
5
  private readonly repository;
5
6
  constructor(repository: RegistryOperatorRepository);
7
+ /** find operators */
8
+ find<P extends string = never>(where: FilterQuery<RegistryOperator>, options?: FindOptions<RegistryOperator, P>): Promise<RegistryOperator[]>;
6
9
  /** find all operators */
7
10
  findAll(): Promise<RegistryOperator[]>;
8
11
  /** find operator by index */
@@ -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');
@@ -11,9 +12,15 @@ exports.RegistryOperatorStorageService = class RegistryOperatorStorageService {
11
12
  constructor(repository) {
12
13
  this.repository = repository;
13
14
  }
15
+ /** find operators */
16
+ async find(where, options) {
17
+ return await this.repository.find(where, options);
18
+ }
14
19
  /** find all operators */
15
20
  async findAll() {
16
- return await this.repository.findAll();
21
+ return await this.repository.findAll({
22
+ orderBy: [{ index: core.QueryOrder.ASC }],
23
+ });
17
24
  }
18
25
  /** find operator by index */
19
26
  async findOneByIndex(operatorIndex) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lido-nestjs/registry",
3
- "version": "1.1.3",
3
+ "version": "1.4.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "MIT",
@@ -30,8 +30,8 @@
30
30
  "dependencies": {
31
31
  "@lido-nestjs/contracts": "2.1.0",
32
32
  "@lido-nestjs/decorators": "1.0.0",
33
- "@lido-nestjs/logger": "1.1.0",
34
- "@lido-nestjs/utils": "1.1.0",
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": {
@@ -45,7 +45,7 @@
45
45
  "tslib": "^2.3.1"
46
46
  },
47
47
  "devDependencies": {
48
- "@lido-nestjs/execution": "1.7.0",
48
+ "@lido-nestjs/execution": "1.7.1",
49
49
  "@mikro-orm/core": "^5.2.0",
50
50
  "@mikro-orm/knex": "^5.2.0",
51
51
  "@mikro-orm/nestjs": "^5.0.2",