UNPKG

ethsub

Version:

A bridge between ethereum and substrate

135 lines (134 loc) 4.46 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.init = exports.Service = void 0; const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const level_1 = __importDefault(require("level")); const use_services_1 = require("use-services"); const types_1 = require("./types"); const services_1 = require("./services"); const ETH_BN_KEY = "bn:eth"; const SUB_BN_KEY = "bn:sub"; class Service { constructor(option) { this.args = option.args; } async [use_services_1.INIT_KEY]() { await fs_1.default.promises.mkdir(this.args.dataDir, { recursive: true }); this.db = (0, level_1.default)(path_1.default.resolve(this.args.dataDir, "db"), { valueEncoding: "json", }); } async storeEthBlockNum(blockNum) { await this.db.put(ETH_BN_KEY, blockNum); } async loadEthBlockNum() { const value = await this.safeGet(ETH_BN_KEY); return value || 0; } async storeSubBlockNum(blockNum) { await this.db.put(SUB_BN_KEY, blockNum); } async loadSubBlockNum() { const value = await this.safeGet(SUB_BN_KEY); return value || 0; } async storeMsg(msg) { const key = this.stringifyMsgKey(msg); await this.db .batch() .put(key, { payload: msg.payload, name: msg.resource.name, }) .put(`${key}:${types_1.BridgeMsgStatus.Pending}`, Date.now()) .write(); } async loadMsg(key) { const value = await this.safeGet(key); if (!value) return; const { source, destination, nonce } = this.parseMsgKey(key); const { name, payload } = value; const resource = services_1.srvs.settings.resources.find((v) => v.name === name); return { source, destination, nonce, resource, type: resource.type, payload, }; } async storeMsgStatus(msg, status) { const key = this.stringifyMsgKey(msg); const batch = this.db.batch(); for (const statusValue in types_1.BridgeMsgStatus) { if (/^\d+$/.test(statusValue)) { if (statusValue === status.toString()) { batch.put(`${key}:${statusValue}`, Date.now()); } else { batch.del(`${key}:${statusValue}`); } } } await batch.write(); } async loadMsgStatus(msg) { const key = this.stringifyMsgKey(msg); const keys = []; for (const statusValue in types_1.BridgeMsgStatus) { if (/^\d+$/.test(statusValue)) { keys.push(`${key}:${statusValue}`); } } const values = await this.db.getMany(keys); for (let i = 0; i < values.length; i++) { return i; } return types_1.BridgeMsgStatus.Pending; } async nextMsg(source, destination) { const re = new RegExp(`^msg:${source}:${destination}:\\d+:${types_1.BridgeMsgStatus.Pending}$`); const key = await this.firstKey((key) => re.test(key)); if (!key) return; const { nonce } = this.parseMsgKey(key); return this.loadMsg(this.stringifyMsgKey({ source, destination, nonce })); } async safeGet(key) { try { const value = await this.db.get(key); return value; } catch (_a) { return null; } } async firstKey(pred = (_) => true) { for await (const [key] of this.db.iterator({ values: false })) { if (pred(key)) return key; } } parseMsgKey(key) { const [source, destination, nonce, status] = key .slice(4) .split(":") .map((v) => parseInt(v)); return { source, destination, nonce, status }; } stringifyMsgKey(msg, status) { let key = `msg:${msg.source}:${msg.destination}:${msg.nonce}`; if (typeof status !== "undefined") { key += ":" + status; } return key; } } exports.Service = Service; exports.init = (0, use_services_1.createInitFn)(Service);