@ocap/resolver 1.18.153 → 1.18.155

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
@@ -162,7 +162,7 @@ module.exports = class OCAPResolver {
162
162
  * @param {object} params.filter bloom filter to do anti-replay check
163
163
  * @param {bool} params.validateTokenConfig should we validate token supply and token-holder balance, should be disabled when starting an existing chain
164
164
  */
165
- constructor({ statedb, indexdb, config, filter, validateTokenConfig = true }) {
165
+ constructor({ statedb, indexdb, config, filter, validateTokenConfig = true, logger }) {
166
166
  if (!statedb) {
167
167
  throw new Error('OCAP Resolver requires a valid statedb implementation to work');
168
168
  }
@@ -170,6 +170,8 @@ module.exports = class OCAPResolver {
170
170
  throw new Error('OCAP Resolver requires a valid indexdb implementation to work');
171
171
  }
172
172
 
173
+ this.logger = logger || { info: debug, warn: debug, error: debug, debug };
174
+
173
175
  this.statedb = statedb;
174
176
  this.indexdb = indexdb;
175
177
  this.filter = filter;
@@ -208,7 +210,10 @@ module.exports = class OCAPResolver {
208
210
  }
209
211
 
210
212
  async sendTx({ tx: txBase64 }, ctx = {}) {
211
- debug('sendTx', txBase64);
213
+ this.logger.info('sendTx', {
214
+ txBase64,
215
+ request: ctx.request,
216
+ });
212
217
 
213
218
  if (process.env.CHAIN_MODE === 'readonly') {
214
219
  throw new CustomError('FORBIDDEN', 'This chain node is running in readonly mode');
@@ -222,6 +227,7 @@ module.exports = class OCAPResolver {
222
227
  indexdb: this.indexdb,
223
228
  config: this.config,
224
229
  filter: this.filter,
230
+ logger: this.logger,
225
231
  extra: ctx,
226
232
  };
227
233
 
@@ -683,7 +689,12 @@ module.exports = class OCAPResolver {
683
689
 
684
690
  async verifyAccountRisk(args, ctx) {
685
691
  return tokenFlow.verifyAccountRisk(
686
- { ...args, accountLimit: process.env.VERIFY_RISK_ACCOUNT_LIMIT, txLimit: process.env.VERIFY_RISK_TX_LIMIT },
692
+ {
693
+ ...args,
694
+ accountLimit: process.env.VERIFY_RISK_ACCOUNT_LIMIT,
695
+ txLimit: process.env.VERIFY_RISK_TX_LIMIT,
696
+ tolerance: process.env.VERIFY_RISK_TOLERANCE,
697
+ },
687
698
  this,
688
699
  ctx
689
700
  );
package/lib/token-flow.js CHANGED
@@ -131,23 +131,17 @@ const getInitialBalance = (address, config) => {
131
131
  return account ? fromTokenToUnit(account.balance) : ZERO;
132
132
  };
133
133
 
134
- const fixMigrateReceipts = async ({ accountAddress, tx }, resolver) => {
134
+ const fixMigrateReceipts = async (tx, resolver) => {
135
135
  const migrationChain = await resolver.getMigrationChain();
136
- const address = migrationChain.findAddressAtTime(accountAddress, new Date(tx.time));
137
- const migrations = migrationChain.getMigrationHistory(accountAddress);
138
-
139
- // fix receipts address
140
- if (address && migrations.length) {
141
- tx.receipts.forEach((receipt) => {
142
- if (migrations.some((x) => isSameDid(x.address, receipt.address))) {
143
- receipt.address = address;
144
- }
145
- });
146
- }
136
+ const txTime = new Date(tx.time);
137
+
138
+ tx.receipts?.forEach((receipt) => {
139
+ receipt.address = migrationChain.findAddressAtTime(receipt.address, txTime);
140
+ });
147
141
  };
148
142
 
149
143
  const verifyAccountRisk = async (
150
- { accountAddress, tokenAddress, accountLimit = 400, txLimit = 10000 },
144
+ { accountAddress, tokenAddress, accountLimit = 400, txLimit = 10000, tolerance = '0.0000000001' },
151
145
  resolver,
152
146
  ctx = {}
153
147
  ) => {
@@ -160,7 +154,8 @@ const verifyAccountRisk = async (
160
154
  const checkedAccounts = new Map();
161
155
  const checkedTx = new Map();
162
156
  const accountQueue = [accountAddress];
163
-
157
+ const tokenState = await resolver.tokenCache.get(tokenAddress);
158
+ const toleranceUnit = fromTokenToUnit(tolerance, tokenState?.decimal);
164
159
  const vaultAccounts = getVaultAccounts(resolver.config);
165
160
 
166
161
  while (accountQueue.length) {
@@ -179,8 +174,10 @@ const verifyAccountRisk = async (
179
174
  const address = accountQueue.pop();
180
175
  // Avoid circular query
181
176
  if (checkedAccounts.has(address)) continue;
182
- // skip trusted accounts
183
- if (await resolver.filter.isTrusted(address)) {
177
+
178
+ const trustedConfig = await resolver.filter?.getTrustedAccountConfig(address);
179
+ // Skip trusted accounts that do not have tolerance configured
180
+ if (trustedConfig && !trustedConfig.tolerance) {
184
181
  checkedAccounts.set(address, true);
185
182
  continue;
186
183
  }
@@ -213,14 +210,12 @@ const verifyAccountRisk = async (
213
210
  // Parse txs to get transfer amounts
214
211
  for (const tx of transactions) {
215
212
  // fix migrate receipts
216
- if (accountState.migratedFrom?.length || accountState.migratedTo?.length) {
217
- await fixMigrateReceipts({ accountAddress: address, tx }, resolver, ctx);
218
- }
213
+ await fixMigrateReceipts(tx, resolver, ctx);
214
+
219
215
  // cache tx
220
216
  if (!checkedTx.has(tx.hash)) {
221
217
  checkedTx.set(tx.hash, await getTransferList(tx, tokenAddress));
222
218
  }
223
-
224
219
  const { transferInList, transferOutList } = checkedTx.get(tx.hash);
225
220
 
226
221
  // Calculate the total amount of transfer for this address
@@ -261,7 +256,13 @@ const verifyAccountRisk = async (
261
256
  checkedAccounts.set(address, true);
262
257
 
263
258
  // Check if the balance not matches the transfer records
264
- if (!transferIn.eq(transferOut.add(new BN(balance)))) {
259
+ if (
260
+ transferIn
261
+ .sub(transferOut.add(new BN(balance)))
262
+ .add(fromTokenToUnit(trustedConfig?.tolerance || 0))
263
+ .abs()
264
+ .gt(toleranceUnit)
265
+ ) {
265
266
  debug('Account balance does not match transfer records', {
266
267
  address,
267
268
  transferIn: transferIn.toString(),
@@ -339,7 +340,7 @@ const listTokenFlows = async (
339
340
 
340
341
  for (const tx of transactions) {
341
342
  // fix migrate receipts
342
- await fixMigrateReceipts({ accountAddress: address, tx }, resolver, ctx);
343
+ await fixMigrateReceipts(tx, resolver, ctx);
343
344
  // cache tx
344
345
  if (!checkedTx.has(tx.hash)) {
345
346
  checkedTx.set(tx.hash, await getTransferFlow(tx, tokenAddress));
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.18.153",
6
+ "version": "1.18.155",
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.18.153",
26
- "@arcblock/did-util": "1.18.153",
27
- "@arcblock/validator": "1.18.153",
28
- "@ocap/config": "1.18.153",
29
- "@ocap/indexdb": "1.18.153",
30
- "@ocap/mcrypto": "1.18.153",
31
- "@ocap/message": "1.18.153",
32
- "@ocap/state": "1.18.153",
33
- "@ocap/tx-protocols": "1.18.153",
34
- "@ocap/util": "1.18.153",
25
+ "@arcblock/did": "1.18.155",
26
+ "@arcblock/did-util": "1.18.155",
27
+ "@arcblock/validator": "1.18.155",
28
+ "@ocap/config": "1.18.155",
29
+ "@ocap/indexdb": "1.18.155",
30
+ "@ocap/mcrypto": "1.18.155",
31
+ "@ocap/message": "1.18.155",
32
+ "@ocap/state": "1.18.155",
33
+ "@ocap/tx-protocols": "1.18.155",
34
+ "@ocap/util": "1.18.155",
35
35
  "debug": "^4.3.6",
36
36
  "lodash": "^4.17.21"
37
37
  },
38
- "gitHead": "ad18c565becef73d6ee782502c3f4858de43b68b"
38
+ "gitHead": "3d0a23a37564c89d4cf8f374823835efdb6eb24b"
39
39
  }