@ocap/statedb-fs 1.28.9 → 1.29.1
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/README.md +1 -2
- package/esm/db.d.mts +29 -0
- package/esm/db.mjs +96 -0
- package/esm/index.d.mts +2 -0
- package/esm/index.mjs +3 -0
- package/esm/package.mjs +6 -0
- package/esm/table/account.d.mts +17 -0
- package/esm/table/account.mjs +27 -0
- package/esm/table/balance.d.mts +23 -0
- package/esm/table/balance.mjs +42 -0
- package/esm/table/base.d.mts +38 -0
- package/esm/table/base.mjs +108 -0
- package/esm/table/rollup.d.mts +14 -0
- package/esm/table/rollup.mjs +20 -0
- package/esm/table/token.d.mts +14 -0
- package/esm/table/token.mjs +17 -0
- package/lib/_virtual/rolldown_runtime.cjs +29 -0
- package/lib/db.cjs +98 -0
- package/lib/db.d.cts +29 -0
- package/lib/index.cjs +4 -0
- package/lib/index.d.cts +2 -0
- package/lib/package.cjs +18 -0
- package/lib/table/account.cjs +29 -0
- package/lib/table/account.d.cts +17 -0
- package/lib/table/balance.cjs +43 -0
- package/lib/table/balance.d.cts +23 -0
- package/lib/table/base.cjs +115 -0
- package/lib/table/base.d.cts +38 -0
- package/lib/table/rollup.cjs +21 -0
- package/lib/table/rollup.d.cts +14 -0
- package/lib/table/token.cjs +18 -0
- package/lib/table/token.d.cts +14 -0
- package/package.json +33 -9
- package/lib/db.js +0 -54
- package/lib/index.js +0 -1
- package/lib/table/account.js +0 -20
- package/lib/table/balance.js +0 -41
- package/lib/table/base.js +0 -150
- package/lib/table/rollup.js +0 -13
- package/lib/table/token.js +0 -13
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2
|
+
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
3
|
+
const require_table_base = require('./base.cjs');
|
|
4
|
+
let _ocap_state_lib_states_account = require("@ocap/state/lib/states/account");
|
|
5
|
+
|
|
6
|
+
//#region src/table/account.ts
|
|
7
|
+
/**
|
|
8
|
+
* Account 表
|
|
9
|
+
* 扩展基础表,增加账户迁移追踪功能
|
|
10
|
+
*/
|
|
11
|
+
var AccountTable = class extends require_table_base.default {
|
|
12
|
+
async _get(address, context = {}) {
|
|
13
|
+
const { traceMigration = true, ...restContext } = context;
|
|
14
|
+
const current = await super._get((0, _ocap_state_lib_states_account.ensureChecksumAddress)(address), restContext);
|
|
15
|
+
if (current && traceMigration && Array.isArray(current.migratedTo) && current.migratedTo.length) return this._get(current.migratedTo[0], context);
|
|
16
|
+
return current;
|
|
17
|
+
}
|
|
18
|
+
_create(key, attrs = {}, ctx) {
|
|
19
|
+
const address = (0, _ocap_state_lib_states_account.ensureChecksumAddress)(key);
|
|
20
|
+
return super._create(address, {
|
|
21
|
+
...attrs,
|
|
22
|
+
address
|
|
23
|
+
}, ctx);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
var account_default = AccountTable;
|
|
27
|
+
|
|
28
|
+
//#endregion
|
|
29
|
+
exports.default = account_default;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import FsTable from "./base.cjs";
|
|
2
|
+
import { IAccountState, IOperationContext } from "@ocap/types";
|
|
3
|
+
|
|
4
|
+
//#region src/table/account.d.ts
|
|
5
|
+
interface AccountOperationContext extends IOperationContext {
|
|
6
|
+
traceMigration?: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Account 表
|
|
10
|
+
* 扩展基础表,增加账户迁移追踪功能
|
|
11
|
+
*/
|
|
12
|
+
declare class AccountTable extends FsTable<IAccountState> {
|
|
13
|
+
_get(address: string | Record<string, unknown>, context?: AccountOperationContext): Promise<IAccountState | null>;
|
|
14
|
+
_create(key: string | Record<string, unknown>, attrs?: Partial<IAccountState>, ctx?: IOperationContext): Promise<IAccountState>;
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { AccountTable as default };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2
|
+
const require_table_base = require('./base.cjs');
|
|
3
|
+
|
|
4
|
+
//#region src/table/balance.ts
|
|
5
|
+
/**
|
|
6
|
+
* Balance 表
|
|
7
|
+
* 扩展基础表,增加余额管理功能
|
|
8
|
+
*/
|
|
9
|
+
var BalanceTable = class extends require_table_base.default {
|
|
10
|
+
async getBalance(address, _context) {
|
|
11
|
+
return (await this.collection.find({ address }) || []).reduce((acc, token) => {
|
|
12
|
+
acc[token.tokenAddress] = token.balance;
|
|
13
|
+
return acc;
|
|
14
|
+
}, {});
|
|
15
|
+
}
|
|
16
|
+
async updateBalance({ address, tokens, context = {} }, ctx) {
|
|
17
|
+
if (!Object.keys(tokens).length) return {};
|
|
18
|
+
const tokenBalances = await this.getBalance(address);
|
|
19
|
+
const updatedTokens = Object.keys(tokens).filter((token) => tokenBalances[token] && tokenBalances[token] !== "0" || tokens[token] && tokens[token] !== "0").filter((token) => tokenBalances[token] !== tokens[token]);
|
|
20
|
+
await Promise.all(updatedTokens.map(async (token) => {
|
|
21
|
+
const key = {
|
|
22
|
+
address,
|
|
23
|
+
tokenAddress: token
|
|
24
|
+
};
|
|
25
|
+
if (tokenBalances[token]) await this.update(key, {
|
|
26
|
+
...key,
|
|
27
|
+
balance: tokens[token],
|
|
28
|
+
context
|
|
29
|
+
}, ctx);
|
|
30
|
+
else await this.create(key, {
|
|
31
|
+
...key,
|
|
32
|
+
balance: tokens[token],
|
|
33
|
+
context
|
|
34
|
+
}, ctx);
|
|
35
|
+
tokenBalances[token] = tokens[token];
|
|
36
|
+
}));
|
|
37
|
+
return tokens;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
var balance_default = BalanceTable;
|
|
41
|
+
|
|
42
|
+
//#endregion
|
|
43
|
+
exports.default = balance_default;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import FsTable from "./base.cjs";
|
|
2
|
+
import { IBalanceState, IOperationContext } from "@ocap/types";
|
|
3
|
+
|
|
4
|
+
//#region src/table/balance.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Balance 表
|
|
8
|
+
* 扩展基础表,增加余额管理功能
|
|
9
|
+
*/
|
|
10
|
+
declare class BalanceTable extends FsTable<IBalanceState> {
|
|
11
|
+
getBalance(address: string, _context?: IOperationContext): Promise<Record<string, string>>;
|
|
12
|
+
updateBalance({
|
|
13
|
+
address,
|
|
14
|
+
tokens,
|
|
15
|
+
context
|
|
16
|
+
}: {
|
|
17
|
+
address: string;
|
|
18
|
+
tokens: Record<string, string>;
|
|
19
|
+
context?: unknown;
|
|
20
|
+
}, ctx?: IOperationContext): Promise<Record<string, string>>;
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
export { BalanceTable as default };
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2
|
+
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
3
|
+
const require_package = require('../package.cjs');
|
|
4
|
+
let _ocap_statedb = require("@ocap/statedb");
|
|
5
|
+
let node_path = require("node:path");
|
|
6
|
+
node_path = require_rolldown_runtime.__toESM(node_path);
|
|
7
|
+
let lodash_omit = require("lodash/omit");
|
|
8
|
+
lodash_omit = require_rolldown_runtime.__toESM(lodash_omit);
|
|
9
|
+
let lokijs = require("lokijs");
|
|
10
|
+
lokijs = require_rolldown_runtime.__toESM(lokijs);
|
|
11
|
+
let lokijs_src_loki_fs_structured_adapter = require("lokijs/src/loki-fs-structured-adapter");
|
|
12
|
+
lokijs_src_loki_fs_structured_adapter = require_rolldown_runtime.__toESM(lokijs_src_loki_fs_structured_adapter);
|
|
13
|
+
let debug = require("debug");
|
|
14
|
+
debug = require_rolldown_runtime.__toESM(debug);
|
|
15
|
+
|
|
16
|
+
//#region src/table/base.ts
|
|
17
|
+
const debug$1 = (0, debug.default)(require_package.name);
|
|
18
|
+
/**
|
|
19
|
+
* 文件系统表基类
|
|
20
|
+
* 使用 LokiJS + FSAdapter 作为底层存储
|
|
21
|
+
*/
|
|
22
|
+
var FsTable = class FsTable extends _ocap_statedb.StateDBTable {
|
|
23
|
+
constructor({ name: name$1, dataDir, uniqIndex, balanceTable, syncBalance = false }) {
|
|
24
|
+
super(uniqIndex);
|
|
25
|
+
this.name = name$1;
|
|
26
|
+
this.dataDir = dataDir;
|
|
27
|
+
this.collection = null;
|
|
28
|
+
this.balanceTable = balanceTable;
|
|
29
|
+
this.syncBalance = syncBalance;
|
|
30
|
+
if (this.syncBalance && !this.balanceTable) throw new Error("balanceTable is required when syncBalance is true");
|
|
31
|
+
const adapter = new lokijs_src_loki_fs_structured_adapter.default();
|
|
32
|
+
const db = new lokijs.default(node_path.default.join(dataDir, `${name$1}.db`), {
|
|
33
|
+
adapter,
|
|
34
|
+
autoload: true,
|
|
35
|
+
autosave: true,
|
|
36
|
+
autosaveInterval: 1e3,
|
|
37
|
+
autoloadCallback: () => {
|
|
38
|
+
this.collection = db.getCollection(name$1);
|
|
39
|
+
if (this.collection === null) this.collection = db.addCollection(name$1, {
|
|
40
|
+
unique: [this.primaryKey],
|
|
41
|
+
clone: true
|
|
42
|
+
});
|
|
43
|
+
this.markReady();
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
async _create(key, attrs = {}, _context) {
|
|
48
|
+
const id = this.generatePrimaryKey(key);
|
|
49
|
+
if (await FsTable.prototype._get.call(this, id)) throw new Error(`${this.name} already exists: ${key}`);
|
|
50
|
+
debug$1(`insert ${this.name}`, attrs);
|
|
51
|
+
const insertAttrs = { ...attrs };
|
|
52
|
+
if (this.syncBalance) delete insertAttrs.tokens;
|
|
53
|
+
const result = await this.collection.insert({
|
|
54
|
+
[this.primaryKey]: id,
|
|
55
|
+
...insertAttrs
|
|
56
|
+
});
|
|
57
|
+
if (this.syncBalance && attrs.tokens) {
|
|
58
|
+
debug$1(`update balance for ${this.name}`, attrs);
|
|
59
|
+
result.tokens = await this.balanceTable.updateBalance({
|
|
60
|
+
address: attrs.address,
|
|
61
|
+
tokens: attrs.tokens,
|
|
62
|
+
context: attrs.context
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
async _get(key, _context) {
|
|
68
|
+
if (!key) return null;
|
|
69
|
+
const id = this.generatePrimaryKey(key);
|
|
70
|
+
const result = await this.collection.by(this.primaryKey, id);
|
|
71
|
+
if (result && this.syncBalance) {
|
|
72
|
+
const balance = await this.balanceTable.getBalance(result.address);
|
|
73
|
+
result.tokens = {
|
|
74
|
+
...result.tokens || {},
|
|
75
|
+
...balance
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
_history(_key, _context) {
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
async _update(key, updates, _context) {
|
|
84
|
+
const id = this.generatePrimaryKey(key);
|
|
85
|
+
const doc = await FsTable.prototype._get.call(this, id);
|
|
86
|
+
if (!doc) throw new Error(`${this.name} does not exists: ${key}`);
|
|
87
|
+
Object.assign(doc, updates);
|
|
88
|
+
const updateAttrs = { ...doc };
|
|
89
|
+
if (this.syncBalance) delete updateAttrs.tokens;
|
|
90
|
+
await this.collection.update(updateAttrs);
|
|
91
|
+
if (this.syncBalance && doc.tokens) {
|
|
92
|
+
debug$1(`update balance for ${this.name}`, doc);
|
|
93
|
+
doc.tokens = await this.balanceTable.updateBalance({
|
|
94
|
+
address: doc.address,
|
|
95
|
+
tokens: doc.tokens,
|
|
96
|
+
context: doc.context
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return doc;
|
|
100
|
+
}
|
|
101
|
+
updateOrCreate(exist, state, ctx) {
|
|
102
|
+
const id = this.generatePrimaryKey(state);
|
|
103
|
+
const attrs = (0, lodash_omit.default)(state, this.primaryKey);
|
|
104
|
+
if (!id) throw new Error("Cannot update or create without uniq index");
|
|
105
|
+
if (exist) return this.update(id, attrs, ctx);
|
|
106
|
+
return this.create(id, attrs, ctx);
|
|
107
|
+
}
|
|
108
|
+
_reset(_context) {
|
|
109
|
+
this.collection.removeWhere({});
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
var base_default = FsTable;
|
|
113
|
+
|
|
114
|
+
//#endregion
|
|
115
|
+
exports.default = base_default;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { StateDBTable } from "@ocap/statedb";
|
|
2
|
+
import { IBalanceTable, IOperationContext } from "@ocap/types";
|
|
3
|
+
import Lokijs from "lokijs";
|
|
4
|
+
|
|
5
|
+
//#region src/table/base.d.ts
|
|
6
|
+
interface FsTableOptions {
|
|
7
|
+
name: string;
|
|
8
|
+
dataDir: string;
|
|
9
|
+
uniqIndex: string | string[];
|
|
10
|
+
balanceTable?: IBalanceTable;
|
|
11
|
+
syncBalance?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 文件系统表基类
|
|
15
|
+
* 使用 LokiJS + FSAdapter 作为底层存储
|
|
16
|
+
*/
|
|
17
|
+
declare class FsTable<T = unknown> extends StateDBTable<T> {
|
|
18
|
+
name: string;
|
|
19
|
+
dataDir: string;
|
|
20
|
+
collection: Lokijs.Collection | null;
|
|
21
|
+
balanceTable?: IBalanceTable;
|
|
22
|
+
syncBalance: boolean;
|
|
23
|
+
constructor({
|
|
24
|
+
name,
|
|
25
|
+
dataDir,
|
|
26
|
+
uniqIndex,
|
|
27
|
+
balanceTable,
|
|
28
|
+
syncBalance
|
|
29
|
+
}: FsTableOptions);
|
|
30
|
+
_create(key: string | Record<string, unknown>, attrs?: Partial<T>, _context?: IOperationContext): Promise<T>;
|
|
31
|
+
_get(key: string | Record<string, unknown>, _context?: IOperationContext): Promise<T | null>;
|
|
32
|
+
_history(_key?: string | Record<string, unknown>, _context?: IOperationContext): T[];
|
|
33
|
+
_update(key: string | Record<string, unknown>, updates: Partial<T>, _context?: IOperationContext): Promise<T>;
|
|
34
|
+
updateOrCreate(exist: unknown, state: Partial<T>, ctx?: IOperationContext): Promise<T>;
|
|
35
|
+
_reset(_context?: IOperationContext): void;
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { FsTable as default };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2
|
+
const require_table_base = require('./base.cjs');
|
|
3
|
+
|
|
4
|
+
//#region src/table/rollup.ts
|
|
5
|
+
/**
|
|
6
|
+
* Rollup 表
|
|
7
|
+
* 扩展基础表,增加按代币查询功能
|
|
8
|
+
*/
|
|
9
|
+
var RollupTable = class extends require_table_base.default {
|
|
10
|
+
async existByToken(token) {
|
|
11
|
+
if (!token) return false;
|
|
12
|
+
return this.collection.count({
|
|
13
|
+
tokenAddress: token,
|
|
14
|
+
paused: false
|
|
15
|
+
}) > 0;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
var rollup_default = RollupTable;
|
|
19
|
+
|
|
20
|
+
//#endregion
|
|
21
|
+
exports.default = rollup_default;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import FsTable from "./base.cjs";
|
|
2
|
+
import { IRollupState } from "@ocap/types";
|
|
3
|
+
|
|
4
|
+
//#region src/table/rollup.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Rollup 表
|
|
8
|
+
* 扩展基础表,增加按代币查询功能
|
|
9
|
+
*/
|
|
10
|
+
declare class RollupTable extends FsTable<IRollupState> {
|
|
11
|
+
existByToken(token?: string | null): Promise<boolean>;
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { RollupTable as default };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2
|
+
const require_table_base = require('./base.cjs');
|
|
3
|
+
|
|
4
|
+
//#region src/table/token.ts
|
|
5
|
+
/**
|
|
6
|
+
* Token 表
|
|
7
|
+
* 扩展基础表,增加按符号查询功能
|
|
8
|
+
*/
|
|
9
|
+
var TokenTable = class extends require_table_base.default {
|
|
10
|
+
async existBySymbol(symbol) {
|
|
11
|
+
if (!symbol) throw new Error("param symbol is required");
|
|
12
|
+
return this.collection.count({ symbol }) > 0;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
var token_default = TokenTable;
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
exports.default = token_default;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import FsTable from "./base.cjs";
|
|
2
|
+
import { ITokenState } from "@ocap/types";
|
|
3
|
+
|
|
4
|
+
//#region src/table/token.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Token 表
|
|
8
|
+
* 扩展基础表,增加按符号查询功能
|
|
9
|
+
*/
|
|
10
|
+
declare class TokenTable extends FsTable<ITokenState> {
|
|
11
|
+
existBySymbol(symbol?: string | null): Promise<boolean>;
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { TokenTable as default };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ocap/statedb-fs",
|
|
3
3
|
"description": "OCAP statedb adapter that uses fs as backend",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.29.1",
|
|
5
5
|
"author": "wangshijun <shijun@arcblock.io> (https://www.arcblock.io)",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/ArcBlock/blockchain/issues",
|
|
@@ -21,27 +21,51 @@
|
|
|
21
21
|
"fs"
|
|
22
22
|
],
|
|
23
23
|
"license": "Apache-2.0",
|
|
24
|
-
"
|
|
24
|
+
"type": "module",
|
|
25
|
+
"main": "./lib/index.cjs",
|
|
26
|
+
"module": "./esm/index.mjs",
|
|
27
|
+
"types": "./esm/index.d.mts",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./esm/index.d.mts",
|
|
31
|
+
"import": "./esm/index.mjs",
|
|
32
|
+
"default": "./lib/index.cjs"
|
|
33
|
+
},
|
|
34
|
+
"./lib/*.js": {
|
|
35
|
+
"types": "./esm/*.d.mts",
|
|
36
|
+
"import": "./esm/*.mjs",
|
|
37
|
+
"default": "./lib/*.cjs"
|
|
38
|
+
},
|
|
39
|
+
"./lib/*": {
|
|
40
|
+
"types": "./esm/*.d.mts",
|
|
41
|
+
"import": "./esm/*.mjs",
|
|
42
|
+
"default": "./lib/*.cjs"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
25
45
|
"files": [
|
|
26
|
-
"lib"
|
|
46
|
+
"lib",
|
|
47
|
+
"esm"
|
|
27
48
|
],
|
|
28
49
|
"repository": {
|
|
29
50
|
"type": "git",
|
|
30
51
|
"url": "https://github.com/ArcBlock/blockchain/tree/master/statedb/fs"
|
|
31
52
|
},
|
|
32
53
|
"scripts": {
|
|
54
|
+
"build": "tsdown",
|
|
55
|
+
"prebuild": "rm -rf lib esm",
|
|
33
56
|
"lint": "biome check",
|
|
34
57
|
"lint:fix": "biome check --write",
|
|
35
58
|
"test": "bun test",
|
|
36
|
-
"coverage": "npm run test -- --coverage
|
|
59
|
+
"coverage": "npm run test -- --coverage"
|
|
37
60
|
},
|
|
38
61
|
"gitHead": "87990c8b5e215107fc587c1ced0d6b3e2cd2483e",
|
|
39
62
|
"dependencies": {
|
|
40
|
-
"@ocap/state": "1.
|
|
41
|
-
"@ocap/statedb": "1.
|
|
42
|
-
"@ocap/
|
|
43
|
-
"
|
|
44
|
-
"
|
|
63
|
+
"@ocap/state": "1.29.1",
|
|
64
|
+
"@ocap/statedb": "1.29.1",
|
|
65
|
+
"@ocap/types": "1.29.1",
|
|
66
|
+
"@ocap/util": "1.29.1",
|
|
67
|
+
"debug": "^4.4.3",
|
|
68
|
+
"lodash": "^4.17.23",
|
|
45
69
|
"lokijs": "^1.5.12"
|
|
46
70
|
}
|
|
47
71
|
}
|
package/lib/db.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
const { StateDB } = require('@ocap/statedb');
|
|
2
|
-
|
|
3
|
-
const Table = require('./table/base');
|
|
4
|
-
const Account = require('./table/account');
|
|
5
|
-
const Token = require('./table/token');
|
|
6
|
-
const Rollup = require('./table/rollup');
|
|
7
|
-
const Balance = require('./table/balance');
|
|
8
|
-
|
|
9
|
-
const { name, version } = require('../package.json');
|
|
10
|
-
|
|
11
|
-
class FsStateDB extends StateDB {
|
|
12
|
-
constructor(dataDir) {
|
|
13
|
-
super();
|
|
14
|
-
|
|
15
|
-
this.name = name;
|
|
16
|
-
this.version = version;
|
|
17
|
-
|
|
18
|
-
this.balance = new Balance({ name: 'balance', dataDir, uniqIndex: ['address', 'tokenAddress'] });
|
|
19
|
-
this.account = new Account({
|
|
20
|
-
name: 'account',
|
|
21
|
-
dataDir,
|
|
22
|
-
uniqIndex: 'address',
|
|
23
|
-
balanceTable: this.balance,
|
|
24
|
-
syncBalance: true,
|
|
25
|
-
});
|
|
26
|
-
this.factory = new Table({
|
|
27
|
-
name: 'factory',
|
|
28
|
-
dataDir,
|
|
29
|
-
uniqIndex: 'address',
|
|
30
|
-
syncBalance: true,
|
|
31
|
-
balanceTable: this.balance,
|
|
32
|
-
});
|
|
33
|
-
this.stake = new Table({
|
|
34
|
-
name: 'stake',
|
|
35
|
-
dataDir,
|
|
36
|
-
uniqIndex: 'address',
|
|
37
|
-
syncBalance: true,
|
|
38
|
-
balanceTable: this.balance,
|
|
39
|
-
});
|
|
40
|
-
this.asset = new Table({ name: 'asset', dataDir, uniqIndex: 'address' });
|
|
41
|
-
this.delegation = new Table({ name: 'delegation', dataDir, uniqIndex: 'address' });
|
|
42
|
-
this.tx = new Table({ name: 'tx', dataDir, uniqIndex: 'hash' });
|
|
43
|
-
this.token = new Token({ name: 'token', dataDir, uniqIndex: 'address' });
|
|
44
|
-
this.chain = new Table({ name: 'chain', dataDir, uniqIndex: 'address' });
|
|
45
|
-
this.rollup = new Rollup({ name: 'rollup', dataDir, uniqIndex: 'address' });
|
|
46
|
-
this.rollupBlock = new Table({ name: 'rollupBlock', dataDir, uniqIndex: 'hash' });
|
|
47
|
-
this.evidence = new Table({ name: 'evidence', dataDir, uniqIndex: 'hash' });
|
|
48
|
-
this.tokenFactory = new Table({ name: 'tokenFactory', dataDir, uniqIndex: 'address' });
|
|
49
|
-
|
|
50
|
-
this.attachReadyListeners();
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
module.exports = FsStateDB;
|
package/lib/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require('./db');
|
package/lib/table/account.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
const { ensureChecksumAddress } = require('@ocap/state/lib/states/account');
|
|
2
|
-
const FsTable = require('./base');
|
|
3
|
-
|
|
4
|
-
class AccountTable extends FsTable {
|
|
5
|
-
async _get(address, { traceMigration = true } = {}) {
|
|
6
|
-
const current = await super._get(ensureChecksumAddress(address));
|
|
7
|
-
if (current && traceMigration && Array.isArray(current.migratedTo) && current.migratedTo.length) {
|
|
8
|
-
return this._get(current.migratedTo[0]);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
return current;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
_create(key, attrs = {}, ctx = {}) {
|
|
15
|
-
const address = ensureChecksumAddress(key);
|
|
16
|
-
return super._create(address, { ...attrs, address }, ctx);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
module.exports = AccountTable;
|
package/lib/table/balance.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
const FsTable = require('./base');
|
|
2
|
-
|
|
3
|
-
class BalanceTable extends FsTable {
|
|
4
|
-
async getBalance(address) {
|
|
5
|
-
const tokens = await this.collection.find({ address });
|
|
6
|
-
|
|
7
|
-
return (tokens || []).reduce((acc, token) => {
|
|
8
|
-
acc[token.tokenAddress] = token.balance;
|
|
9
|
-
return acc;
|
|
10
|
-
}, {});
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
async updateBalance({ address, tokens, context = {} }, ctx) {
|
|
14
|
-
if (!Object.keys(tokens).length) return {};
|
|
15
|
-
|
|
16
|
-
const tokenBalances = await this.getBalance(address);
|
|
17
|
-
const updatedTokens = Object.keys(tokens)
|
|
18
|
-
.filter(
|
|
19
|
-
(token) => (tokenBalances[token] && tokenBalances[token] !== '0') || (tokens[token] && tokens[token] !== '0')
|
|
20
|
-
)
|
|
21
|
-
.filter((token) => tokenBalances[token] !== tokens[token]);
|
|
22
|
-
|
|
23
|
-
await Promise.all(
|
|
24
|
-
updatedTokens.map(async (token) => {
|
|
25
|
-
const key = { address, tokenAddress: token };
|
|
26
|
-
|
|
27
|
-
if (tokenBalances[token]) {
|
|
28
|
-
await this.update(key, { ...key, balance: tokens[token], context }, ctx);
|
|
29
|
-
} else {
|
|
30
|
-
await this.create(key, { ...key, balance: tokens[token], context }, ctx);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
tokenBalances[token] = tokens[token];
|
|
34
|
-
})
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
return tokens;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
module.exports = BalanceTable;
|
package/lib/table/base.js
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
const path = require('node:path');
|
|
2
|
-
const omit = require('lodash/omit');
|
|
3
|
-
const { StateDBTable } = require('@ocap/statedb');
|
|
4
|
-
const Lokijs = require('lokijs');
|
|
5
|
-
const FsAdapter = require('lokijs/src/loki-fs-structured-adapter');
|
|
6
|
-
|
|
7
|
-
const debug = require('debug')(require('../../package.json').name);
|
|
8
|
-
|
|
9
|
-
class FsTable extends StateDBTable {
|
|
10
|
-
/**
|
|
11
|
-
* @param {Object} param
|
|
12
|
-
* @param {string} param.name db name
|
|
13
|
-
* @param {string|string[]} param.uniqIndex primary keys
|
|
14
|
-
* @param {string} param.dataDir data directory for db
|
|
15
|
-
* @param {boolean} param.syncBalance sync balance table when create / update / get
|
|
16
|
-
* @param {BalanceTable} param.balanceTable balance table
|
|
17
|
-
*/
|
|
18
|
-
constructor({ name, dataDir, uniqIndex, balanceTable, syncBalance = false }) {
|
|
19
|
-
super(uniqIndex);
|
|
20
|
-
|
|
21
|
-
this.name = name;
|
|
22
|
-
this.dataDir = dataDir;
|
|
23
|
-
this.uniqIndex = uniqIndex;
|
|
24
|
-
this.collection = null;
|
|
25
|
-
this.balanceTable = balanceTable;
|
|
26
|
-
this.syncBalance = syncBalance;
|
|
27
|
-
|
|
28
|
-
if (this.syncBalance && !this.balanceTable) {
|
|
29
|
-
throw new Error('balanceTable is required when syncBalance is true');
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const adapter = new FsAdapter();
|
|
33
|
-
const db = new Lokijs(path.join(dataDir, `${name}.db`), {
|
|
34
|
-
adapter,
|
|
35
|
-
autoload: true,
|
|
36
|
-
autosave: true,
|
|
37
|
-
autosaveInterval: 1000,
|
|
38
|
-
autoloadCallback: () => {
|
|
39
|
-
this.collection = db.getCollection(name);
|
|
40
|
-
|
|
41
|
-
if (this.collection === null) {
|
|
42
|
-
this.collection = db.addCollection(name, { unique: [this.primaryKey], clone: true });
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
this.markReady();
|
|
46
|
-
},
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
async _create(key, attrs) {
|
|
51
|
-
const id = this.generatePrimaryKey(key);
|
|
52
|
-
// Don't call this._get here cause _get may be overwritten
|
|
53
|
-
const doc = await FsTable.prototype._get.call(this, id);
|
|
54
|
-
if (doc) {
|
|
55
|
-
throw new Error(`${this.name} already exists: ${key}`);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
debug(`insert ${this.name}`, attrs);
|
|
59
|
-
|
|
60
|
-
const insertAttrs = { ...attrs };
|
|
61
|
-
// insert without tokens cause we've migrate token to balance table
|
|
62
|
-
if (this.syncBalance) {
|
|
63
|
-
delete insertAttrs.tokens;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const result = await this.collection.insert({ [this.primaryKey]: id, ...insertAttrs });
|
|
67
|
-
|
|
68
|
-
if (this.syncBalance && attrs.tokens) {
|
|
69
|
-
debug(`update balance for ${this.name}`, attrs);
|
|
70
|
-
|
|
71
|
-
result.tokens = await this.balanceTable.updateBalance({
|
|
72
|
-
address: attrs.address,
|
|
73
|
-
tokens: attrs.tokens,
|
|
74
|
-
context: attrs.context,
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return result;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
async _get(key) {
|
|
82
|
-
if (!key) return null;
|
|
83
|
-
|
|
84
|
-
const id = this.generatePrimaryKey(key);
|
|
85
|
-
const result = await this.collection.by(this.primaryKey, id);
|
|
86
|
-
|
|
87
|
-
if (result && this.syncBalance) {
|
|
88
|
-
const balance = await this.balanceTable.getBalance(result.address);
|
|
89
|
-
result.tokens = { ...(result.tokens || {}), ...balance };
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return result;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
_history() {
|
|
96
|
-
return [];
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
async _update(key, updates) {
|
|
100
|
-
const id = this.generatePrimaryKey(key);
|
|
101
|
-
// Don't call this._get here cause _get may be overwritten
|
|
102
|
-
const doc = await FsTable.prototype._get.call(this, id);
|
|
103
|
-
if (!doc) {
|
|
104
|
-
throw new Error(`${this.name} does not exists: ${key}`);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
Object.assign(doc, updates);
|
|
108
|
-
|
|
109
|
-
const updateAttrs = { ...doc };
|
|
110
|
-
// insert without tokens cause we've migrate token to balance table
|
|
111
|
-
if (this.syncBalance) {
|
|
112
|
-
delete updateAttrs.tokens;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
await this.collection.update(updateAttrs);
|
|
116
|
-
|
|
117
|
-
if (this.syncBalance && doc.tokens) {
|
|
118
|
-
debug(`update balance for ${this.name}`, doc);
|
|
119
|
-
|
|
120
|
-
doc.tokens = await this.balanceTable.updateBalance({
|
|
121
|
-
address: doc.address,
|
|
122
|
-
tokens: doc.tokens,
|
|
123
|
-
context: doc.context,
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return doc;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
updateOrCreate(exist, state, ctx) {
|
|
131
|
-
const id = this.generatePrimaryKey(state);
|
|
132
|
-
const attrs = omit(state, this.primaryKey);
|
|
133
|
-
|
|
134
|
-
if (!id) {
|
|
135
|
-
throw new Error('Cannot update or create without uniq index');
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
if (exist) {
|
|
139
|
-
return this.update(id, attrs, ctx);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
return this.create(id, attrs, ctx);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
_reset() {
|
|
146
|
-
this.collection.removeWhere({});
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
module.exports = FsTable;
|