@ocap/resolver 1.19.4 → 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 +14 -39
- package/lib/token-distribution.js +17 -10
- package/package.json +12 -12
package/lib/index.js
CHANGED
|
@@ -1046,11 +1046,11 @@ module.exports = class OCAPResolver {
|
|
|
1046
1046
|
if (limit && paging.total > limit) {
|
|
1047
1047
|
throw new CustomError('EXCEED_LIMIT', `Total exceeds limit ${limit}`);
|
|
1048
1048
|
}
|
|
1049
|
-
if (paging.total
|
|
1049
|
+
if (paging.total <= pageSize) {
|
|
1050
1050
|
return firstPage;
|
|
1051
1051
|
}
|
|
1052
1052
|
|
|
1053
|
-
const totalPage = Math.
|
|
1053
|
+
const totalPage = Math.ceil(paging.total / pageSize) - 1;
|
|
1054
1054
|
const cursors = new Array(totalPage).fill(true).map((_, i) => (i + 1) * pageSize);
|
|
1055
1055
|
const step = process.env.RESOLVER_BATCH_CONCURRENCY || 3;
|
|
1056
1056
|
let results = firstPage;
|
|
@@ -1282,23 +1282,14 @@ module.exports = class OCAPResolver {
|
|
|
1282
1282
|
* @param {number} [param.concurrency=3] Number of concurrent requests
|
|
1283
1283
|
* @param {number} [param.chunkSize=2000] Maximum number of items to return in each next() call
|
|
1284
1284
|
* @param {number} [param.pageSize=100] Number of items per page
|
|
1285
|
-
* @param {
|
|
1285
|
+
* @param {string} param.timeKey Key to access time in response
|
|
1286
1286
|
* @param {string} param.dataKey Key to access data in response
|
|
1287
1287
|
* @returns {Promise<Array>} Array of fetched items
|
|
1288
1288
|
*/
|
|
1289
|
-
listChunks(fn, { concurrency = 3, chunkSize = 2000, pageSize = 100,
|
|
1290
|
-
let totalPage;
|
|
1291
|
-
let curPage;
|
|
1289
|
+
listChunks(fn, { total, concurrency = 3, chunkSize = 2000, pageSize = 100, timeKey, dataKey }) {
|
|
1292
1290
|
let done = false;
|
|
1293
1291
|
let time;
|
|
1294
|
-
|
|
1295
|
-
const fetchFirstPage = async () => {
|
|
1296
|
-
const { paging, page, [dataKey]: list } = await fn({ size: pageSize, cursor: '0' });
|
|
1297
|
-
const total = paging?.total || page?.total;
|
|
1298
|
-
curPage = 1;
|
|
1299
|
-
totalPage = Math.ceil(total / pageSize);
|
|
1300
|
-
return list;
|
|
1301
|
-
};
|
|
1292
|
+
const totalPage = Math.ceil(total / pageSize);
|
|
1302
1293
|
|
|
1303
1294
|
const next = async () => {
|
|
1304
1295
|
if (done) {
|
|
@@ -1307,28 +1298,10 @@ module.exports = class OCAPResolver {
|
|
|
1307
1298
|
|
|
1308
1299
|
let results = [];
|
|
1309
1300
|
|
|
1310
|
-
// first page
|
|
1311
|
-
if (!totalPage) {
|
|
1312
|
-
const data = await fetchFirstPage();
|
|
1313
|
-
// only 1 page
|
|
1314
|
-
if (data.length < pageSize) {
|
|
1315
|
-
done = true;
|
|
1316
|
-
return data;
|
|
1317
|
-
}
|
|
1318
|
-
|
|
1319
|
-
time = getTime(data[data.length - 1]);
|
|
1320
|
-
results = results.concat(data);
|
|
1321
|
-
|
|
1322
|
-
// limit
|
|
1323
|
-
if (data.length >= chunkSize) {
|
|
1324
|
-
return results;
|
|
1325
|
-
}
|
|
1326
|
-
}
|
|
1327
|
-
|
|
1328
1301
|
// next pages
|
|
1329
|
-
for (; curPage < totalPage; curPage += concurrency) {
|
|
1302
|
+
for (let curPage = 0; curPage < totalPage; curPage += concurrency) {
|
|
1330
1303
|
const batchResults = await Promise.all(
|
|
1331
|
-
new Array(concurrency).fill(true).map(async (_, i) => {
|
|
1304
|
+
new Array(Math.min(concurrency, totalPage - curPage)).fill(true).map(async (_, i) => {
|
|
1332
1305
|
const { [dataKey]: list } = await fn({
|
|
1333
1306
|
size: pageSize,
|
|
1334
1307
|
cursor: i * pageSize,
|
|
@@ -1346,7 +1319,7 @@ module.exports = class OCAPResolver {
|
|
|
1346
1319
|
}
|
|
1347
1320
|
|
|
1348
1321
|
results = results.concat(flatResults);
|
|
1349
|
-
time = results.length ?
|
|
1322
|
+
time = results.length ? results[results.length - 1][timeKey] : null;
|
|
1350
1323
|
|
|
1351
1324
|
// limit
|
|
1352
1325
|
if (results.length >= chunkSize) {
|
|
@@ -1364,7 +1337,7 @@ module.exports = class OCAPResolver {
|
|
|
1364
1337
|
};
|
|
1365
1338
|
}
|
|
1366
1339
|
|
|
1367
|
-
listTransactionsChunks(args = {}, { chunkSize = 2000, pageSize = 100 } = {}) {
|
|
1340
|
+
async listTransactionsChunks(args = {}, { chunkSize = 2000, pageSize = 100 } = {}) {
|
|
1368
1341
|
return this.listChunks(
|
|
1369
1342
|
({ size, time, cursor }) =>
|
|
1370
1343
|
this.listTransactions({
|
|
@@ -1379,14 +1352,15 @@ module.exports = class OCAPResolver {
|
|
|
1379
1352
|
}),
|
|
1380
1353
|
{
|
|
1381
1354
|
dataKey: 'transactions',
|
|
1382
|
-
|
|
1355
|
+
timeKey: 'time',
|
|
1356
|
+
total: await this.indexdb.tx.count(),
|
|
1383
1357
|
chunkSize,
|
|
1384
1358
|
pageSize,
|
|
1385
1359
|
}
|
|
1386
1360
|
);
|
|
1387
1361
|
}
|
|
1388
1362
|
|
|
1389
|
-
listStakeChunks(args = {}, { chunkSize = 2000, pageSize = 100 } = {}) {
|
|
1363
|
+
async listStakeChunks(args = {}, { chunkSize = 2000, pageSize = 100 } = {}) {
|
|
1390
1364
|
return this.listChunks(
|
|
1391
1365
|
({ size, time, cursor }) =>
|
|
1392
1366
|
this.listStakes({
|
|
@@ -1401,7 +1375,8 @@ module.exports = class OCAPResolver {
|
|
|
1401
1375
|
}),
|
|
1402
1376
|
{
|
|
1403
1377
|
dataKey: 'stakes',
|
|
1404
|
-
|
|
1378
|
+
timeKey: 'renaissanceTime',
|
|
1379
|
+
total: await this.indexdb.stake.count(),
|
|
1405
1380
|
chunkSize,
|
|
1406
1381
|
pageSize,
|
|
1407
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
|
-
|
|
52
|
-
|
|
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
|
|
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.
|
|
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.
|
|
26
|
-
"@arcblock/did-util": "1.19.
|
|
27
|
-
"@arcblock/validator": "1.19.
|
|
28
|
-
"@ocap/config": "1.19.
|
|
29
|
-
"@ocap/indexdb": "1.19.
|
|
30
|
-
"@ocap/mcrypto": "1.19.
|
|
31
|
-
"@ocap/message": "1.19.
|
|
32
|
-
"@ocap/state": "1.19.
|
|
33
|
-
"@ocap/tx-protocols": "1.19.
|
|
34
|
-
"@ocap/util": "1.19.
|
|
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": "
|
|
38
|
+
"gitHead": "9f93acb129f6fee316149f3921a98b88dcccfac3"
|
|
39
39
|
}
|