@ocap/resolver 1.19.3 → 1.19.5

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/lib/index.js CHANGED
@@ -692,22 +692,28 @@ module.exports = class OCAPResolver {
692
692
  }
693
693
 
694
694
  verifyAccountRisk(args, ctx) {
695
- return tokenFlow.verifyAccountRisk(
696
- {
697
- ...args,
698
- tokenAddress: toAddress(args.tokenAddress || this.config.token.address),
699
- accountAddress: toAddress(args.accountAddress || ''),
700
- accountLimit: process.env.VERIFY_RISK_ACCOUNT_LIMIT,
701
- txLimit: process.env.VERIFY_RISK_TX_LIMIT,
702
- tolerance: process.env.VERIFY_RISK_TOLERANCE,
703
- },
704
- this,
705
- ctx
706
- );
695
+ if (process.env.TOKEN_FLOW_ENABLED === 'true') {
696
+ return tokenFlow.verifyAccountRisk(
697
+ {
698
+ ...args,
699
+ tokenAddress: toAddress(args.tokenAddress || this.config.token.address),
700
+ accountAddress: toAddress(args.accountAddress || ''),
701
+ accountLimit: process.env.VERIFY_RISK_ACCOUNT_LIMIT,
702
+ txLimit: process.env.VERIFY_RISK_TX_LIMIT,
703
+ tolerance: process.env.VERIFY_RISK_TOLERANCE,
704
+ },
705
+ this,
706
+ ctx
707
+ );
708
+ }
709
+ return null;
707
710
  }
708
711
 
709
712
  listTokenFlows(args, ctx) {
710
- return tokenFlow.listTokenFlows(args, this, ctx);
713
+ if (process.env.TOKEN_FLOW_ENABLED === 'true') {
714
+ return tokenFlow.listTokenFlows(args, this, ctx);
715
+ }
716
+ return [];
711
717
  }
712
718
 
713
719
  async search(args) {
@@ -1040,11 +1046,11 @@ module.exports = class OCAPResolver {
1040
1046
  if (limit && paging.total > limit) {
1041
1047
  throw new CustomError('EXCEED_LIMIT', `Total exceeds limit ${limit}`);
1042
1048
  }
1043
- if (paging.total < pageSize) {
1049
+ if (paging.total <= pageSize) {
1044
1050
  return firstPage;
1045
1051
  }
1046
1052
 
1047
- const totalPage = Math.floor(paging.total / pageSize);
1053
+ const totalPage = Math.ceil(paging.total / pageSize) - 1;
1048
1054
  const cursors = new Array(totalPage).fill(true).map((_, i) => (i + 1) * pageSize);
1049
1055
  const step = process.env.RESOLVER_BATCH_CONCURRENCY || 3;
1050
1056
  let results = firstPage;
@@ -1276,23 +1282,14 @@ module.exports = class OCAPResolver {
1276
1282
  * @param {number} [param.concurrency=3] Number of concurrent requests
1277
1283
  * @param {number} [param.chunkSize=2000] Maximum number of items to return in each next() call
1278
1284
  * @param {number} [param.pageSize=100] Number of items per page
1279
- * @param {Function} param.getTime Function to get timestamp from item
1285
+ * @param {string} param.timeKey Key to access time in response
1280
1286
  * @param {string} param.dataKey Key to access data in response
1281
1287
  * @returns {Promise<Array>} Array of fetched items
1282
1288
  */
1283
- listChunks(fn, { concurrency = 3, chunkSize = 2000, pageSize = 100, getTime, dataKey }) {
1284
- let totalPage;
1285
- let curPage;
1289
+ listChunks(fn, { total, concurrency = 3, chunkSize = 2000, pageSize = 100, timeKey, dataKey }) {
1286
1290
  let done = false;
1287
1291
  let time;
1288
-
1289
- const fetchFirstPage = async () => {
1290
- const { paging, page, [dataKey]: list } = await fn({ size: pageSize, cursor: '0' });
1291
- const total = paging?.total || page?.total;
1292
- curPage = 1;
1293
- totalPage = Math.ceil(total / pageSize);
1294
- return list;
1295
- };
1292
+ const totalPage = Math.ceil(total / pageSize);
1296
1293
 
1297
1294
  const next = async () => {
1298
1295
  if (done) {
@@ -1301,28 +1298,10 @@ module.exports = class OCAPResolver {
1301
1298
 
1302
1299
  let results = [];
1303
1300
 
1304
- // first page
1305
- if (!totalPage) {
1306
- const data = await fetchFirstPage();
1307
- // only 1 page
1308
- if (data.length < pageSize) {
1309
- done = true;
1310
- return data;
1311
- }
1312
-
1313
- time = getTime(data[data.length - 1]);
1314
- results = results.concat(data);
1315
-
1316
- // limit
1317
- if (data.length >= chunkSize) {
1318
- return results;
1319
- }
1320
- }
1321
-
1322
1301
  // next pages
1323
- for (; curPage < totalPage; curPage += concurrency) {
1302
+ for (let curPage = 0; curPage < totalPage; curPage += concurrency) {
1324
1303
  const batchResults = await Promise.all(
1325
- new Array(concurrency).fill(true).map(async (_, i) => {
1304
+ new Array(Math.min(concurrency, totalPage - curPage)).fill(true).map(async (_, i) => {
1326
1305
  const { [dataKey]: list } = await fn({
1327
1306
  size: pageSize,
1328
1307
  cursor: i * pageSize,
@@ -1340,7 +1319,7 @@ module.exports = class OCAPResolver {
1340
1319
  }
1341
1320
 
1342
1321
  results = results.concat(flatResults);
1343
- time = results.length ? getTime(results[results.length - 1]) : null;
1322
+ time = results.length ? results[results.length - 1][timeKey] : null;
1344
1323
 
1345
1324
  // limit
1346
1325
  if (results.length >= chunkSize) {
@@ -1358,7 +1337,7 @@ module.exports = class OCAPResolver {
1358
1337
  };
1359
1338
  }
1360
1339
 
1361
- listTransactionsChunks(args = {}, { chunkSize = 2000, pageSize = 100 } = {}) {
1340
+ async listTransactionsChunks(args = {}, { chunkSize = 2000, pageSize = 100 } = {}) {
1362
1341
  return this.listChunks(
1363
1342
  ({ size, time, cursor }) =>
1364
1343
  this.listTransactions({
@@ -1373,14 +1352,15 @@ module.exports = class OCAPResolver {
1373
1352
  }),
1374
1353
  {
1375
1354
  dataKey: 'transactions',
1376
- getTime: (tx) => tx?.time,
1355
+ timeKey: 'time',
1356
+ total: await this.indexdb.tx.count(),
1377
1357
  chunkSize,
1378
1358
  pageSize,
1379
1359
  }
1380
1360
  );
1381
1361
  }
1382
1362
 
1383
- listStakeChunks(args = {}, { chunkSize = 2000, pageSize = 100 } = {}) {
1363
+ async listStakeChunks(args = {}, { chunkSize = 2000, pageSize = 100 } = {}) {
1384
1364
  return this.listChunks(
1385
1365
  ({ size, time, cursor }) =>
1386
1366
  this.listStakes({
@@ -1395,7 +1375,8 @@ module.exports = class OCAPResolver {
1395
1375
  }),
1396
1376
  {
1397
1377
  dataKey: 'stakes',
1398
- getTime: (state) => state?.time,
1378
+ timeKey: 'renaissanceTime',
1379
+ total: await this.indexdb.stake.count(),
1399
1380
  chunkSize,
1400
1381
  pageSize,
1401
1382
  }
@@ -40,7 +40,7 @@ class TokenDistributionManager {
40
40
  return data && createIndexedTokenDistribution(data);
41
41
  }
42
42
 
43
- async saveDistribution(distribution) {
43
+ async saveDistribution(distribution, isEnsureLatest = true) {
44
44
  const data = createIndexedTokenDistribution(distribution);
45
45
  const indexdbDistribution = await this.getDistribution(data.tokenAddress);
46
46
 
@@ -48,8 +48,10 @@ class TokenDistributionManager {
48
48
  await this.indexdb.tokenDistribution.insert(data);
49
49
  } else {
50
50
  // ensure txTime is latest
51
- const latestTime = Math.max(new Date(indexdbDistribution.txTime).getTime(), new Date(data.txTime).getTime());
52
- data.txTime = new Date(latestTime).toISOString();
51
+ if (isEnsureLatest) {
52
+ const latestTime = Math.max(new Date(indexdbDistribution.txTime).getTime(), new Date(data.txTime).getTime());
53
+ data.txTime = new Date(latestTime).toISOString();
54
+ }
53
55
  await this.indexdb.tokenDistribution.update(data.tokenAddress, data);
54
56
  }
55
57
 
@@ -100,14 +102,14 @@ class TokenDistributionManager {
100
102
  await Promise.all(handlePromises);
101
103
 
102
104
  // update indexdb
103
- await this.saveDistribution(distribution);
105
+ await this.saveDistribution(distribution, false);
104
106
  nextData = await next();
105
107
  }
106
108
 
107
109
  // We cannot distinguish between revokedStake and stake from tx receipts here,
108
110
  // so we need to read all stake transactions and recalculate token distribution based on their revokeTokens and tokens
109
111
  await this.splitStake(distribution, force);
110
- await this.saveDistribution(distribution);
112
+ await this.saveDistribution(distribution, false);
111
113
 
112
114
  const result = createIndexedTokenDistribution(distribution);
113
115
 
@@ -120,20 +122,25 @@ class TokenDistributionManager {
120
122
  * Split out revokedStake / gasStake from stake
121
123
  *
122
124
  * @param {Object} distribution
123
- * @param {boolean} force If force is false, only process transactions after txTime in indexdb. Default is false
124
125
  * @returns {Promise<Object>}
125
126
  */
126
- async splitStake(distribution, force) {
127
+ async splitStake(distribution) {
128
+ const { logger } = this.resolver;
127
129
  const { tokenAddress } = distribution;
128
130
 
129
- const { next } = await this.resolver.listStakeChunks({
130
- timeFilter: !force ? { startDateTime: distribution.txTime } : {},
131
- });
131
+ const { next } = await this.resolver.listStakeChunks();
132
132
 
133
133
  let nextData = await next();
134
134
 
135
135
  // Process transactions in chunks and update indexdb
136
136
  while (nextData.length) {
137
+ logger?.info('Updating stake distribution in chunks', {
138
+ chunkSize: nextData.length,
139
+ startTime: nextData[0].renaissanceTime,
140
+ startAddress: nextData[0].address,
141
+ endTime: nextData[nextData.length - 1].renaissanceTime,
142
+ });
143
+
137
144
  nextData.forEach((stakeState) => {
138
145
  const isGasStake = this.isGasStake(stakeState);
139
146
  const token = stakeState.tokens.find((x) => x.address === tokenAddress);
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.19.3",
6
+ "version": "1.19.5",
7
7
  "description": "GraphQL resolver built upon ocap statedb and GQL layer",
8
8
  "main": "lib/index.js",
9
9
  "files": [
@@ -22,18 +22,18 @@
22
22
  "jest": "^29.7.0"
23
23
  },
24
24
  "dependencies": {
25
- "@arcblock/did": "1.19.3",
26
- "@arcblock/did-util": "1.19.3",
27
- "@arcblock/validator": "1.19.3",
28
- "@ocap/config": "1.19.3",
29
- "@ocap/indexdb": "1.19.3",
30
- "@ocap/mcrypto": "1.19.3",
31
- "@ocap/message": "1.19.3",
32
- "@ocap/state": "1.19.3",
33
- "@ocap/tx-protocols": "1.19.3",
34
- "@ocap/util": "1.19.3",
25
+ "@arcblock/did": "1.19.5",
26
+ "@arcblock/did-util": "1.19.5",
27
+ "@arcblock/validator": "1.19.5",
28
+ "@ocap/config": "1.19.5",
29
+ "@ocap/indexdb": "1.19.5",
30
+ "@ocap/mcrypto": "1.19.5",
31
+ "@ocap/message": "1.19.5",
32
+ "@ocap/state": "1.19.5",
33
+ "@ocap/tx-protocols": "1.19.5",
34
+ "@ocap/util": "1.19.5",
35
35
  "debug": "^4.3.6",
36
36
  "lodash": "^4.17.21"
37
37
  },
38
- "gitHead": "756076dad0df7468beecc95c8effd55f8c4c4f49"
38
+ "gitHead": "9f93acb129f6fee316149f3921a98b88dcccfac3"
39
39
  }