UNPKG

@vechain/connex-driver

Version:
242 lines 20.2 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DriverNoVendor = void 0; const thor_devkit_1 = require("thor-devkit"); const cache_1 = require("./cache"); const common_1 = require("./common"); const promint_1 = require("./promint"); /** class implements Connex.Driver leaves out Vendor related methods */ class DriverNoVendor { constructor(net, genesis, initialHead) { this.net = net; this.genesis = genesis; this.headResolvers = []; this.int = new promint_1.PromInt(); this.cache = new cache_1.Cache(); // to merge concurrent identical remote requests this.pendingRequests = {}; if (initialHead) { this.head = initialHead; } else { this.head = { id: genesis.id, number: genesis.number, timestamp: genesis.timestamp, parentID: genesis.parentID, txsFeatures: genesis.txsFeatures, gasLimit: genesis.gasLimit }; if (genesis.baseFeePerGas) { this.head.baseFeePerGas = genesis.baseFeePerGas; } } void this.headTrackerLoop(); } // close the driver to prevent mem leak close() { this.int.interrupt(); } // implementations pollHead() { return this.int.wrap(new Promise(resolve => { this.headResolvers.push(() => resolve(this.head)); })); } getBlock(revision) { return this.cache.getBlock(revision, () => this.httpGet(`blocks/${revision}`)); } getFeesHistory(newestBlock, blockCount, rewardPercentiles) { return this.cache.getFeesHistory(newestBlock, blockCount, rewardPercentiles || [], () => { const params = { newestBlock: newestBlock.toString(), blockCount: blockCount.toString() }; if (rewardPercentiles && rewardPercentiles.length > 0) { params.rewardPercentiles = rewardPercentiles.join(','); } return this.httpGet('fees/history', params); }); } getPriorityFeeSuggestion() { // No cache since we do not have a key for it return this.httpGet('fees/priority').then(res => res.maxPriorityFeePerGas); } getTransaction(id, allowPending) { return this.cache.getTx(id, () => { const query = { head: this.head.id }; if (allowPending) { query.pending = 'true'; } return this.httpGet(`transactions/${id}`, query); }); } getReceipt(id) { return this.cache.getReceipt(id, () => this.httpGet(`transactions/${id}/receipt`, { head: this.head.id })); } getAccount(addr, revision) { return this.cache.getAccount(addr, revision, () => this.httpGet(`accounts/${addr}`, { revision })); } getCode(addr, revision) { return this.cache.getTied(`code-${addr}`, revision, () => this.httpGet(`accounts/${addr}/code`, { revision })); } getStorage(addr, key, revision) { return this.cache.getTied(`storage-${addr}-${key}`, revision, () => this.httpGet(`accounts/${addr}/storage/${key}`, { revision })); } explain(arg, revision, cacheHints) { const cacheKey = `explain-${thor_devkit_1.blake2b256(JSON.stringify(arg)).toString('hex')}`; return this.cache.getTied(cacheKey, revision, () => this.httpPost('accounts/*', arg, { revision }), cacheHints); } filterEventLogs(arg, cacheHints) { const cacheKey = `event-${thor_devkit_1.blake2b256(JSON.stringify(arg)).toString('hex')}`; return this.cache.getTied(cacheKey, this.head.id, () => this.httpPost('logs/event', arg), cacheHints); } filterTransferLogs(arg, cacheHints) { const cacheKey = `transfer-${thor_devkit_1.blake2b256(JSON.stringify(arg)).toString('hex')}`; return this.cache.getTied(cacheKey, this.head.id, () => this.httpPost('logs/transfer', arg), cacheHints); } signTx(msg, options) { throw new Error('signer not implemented'); } signCert(msg, options) { throw new Error('signer not implemented'); } ////// mergeRequest(req, ...keyParts) { const key = JSON.stringify(keyParts); const pending = this.pendingRequests[key]; // eslint-disable-next-line @typescript-eslint/no-misused-promises if (pending) { return pending; } return this.pendingRequests[key] = (() => __awaiter(this, void 0, void 0, function* () { try { return yield req(); } finally { delete this.pendingRequests[key]; } }))(); } httpGet(path, query) { return this.mergeRequest(() => { return this.net.http('GET', path, { query, validateResponseHeader: this.headerValidator }); }, path, query || ''); } httpPost(path, body, query) { return this.mergeRequest(() => { return this.net.http('POST', path, { query, body, validateResponseHeader: this.headerValidator }); }, path, query || '', body || ''); } get headerValidator() { return (headers) => { const xgid = headers['x-genesis-id']; if (xgid && xgid !== this.genesis.id) { throw new Error(`responded 'x-genesis-id' not matched`); } }; } emitNewHead() { const resolvers = this.headResolvers; this.headResolvers = []; resolvers.forEach(r => r()); } headTrackerLoop() { return __awaiter(this, void 0, void 0, function* () { for (;;) { let attemptWs = false; try { const best = yield this.int.wrap(this.httpGet('blocks/best')); if (best.id !== this.head.id && best.number >= this.head.number) { this.head = { id: best.id, number: best.number, timestamp: best.timestamp, parentID: best.parentID, txsFeatures: best.txsFeatures, gasLimit: best.gasLimit }; if (best.baseFeePerGas) { this.head.baseFeePerGas = best.baseFeePerGas; } this.cache.handleNewBlock(this.head, undefined, best); this.emitNewHead(); if (Date.now() - this.head.timestamp * 1000 < 60 * 1000) { // nearly synced attemptWs = true; } } } catch (err) { if (err instanceof promint_1.InterruptedError) { break; } } if (attemptWs) { try { yield this.trackWs(); } catch (err) { if (err instanceof promint_1.InterruptedError) { break; } } } try { yield this.int.wrap(common_1.sleep(8 * 1000)); } catch (_a) { break; } } }); } trackWs() { return __awaiter(this, void 0, void 0, function* () { const wsPath = `subscriptions/beat2?pos=${this.head.parentID}`; const wsr = this.net.openWebSocketReader(wsPath); try { for (;;) { const data = yield this.int.wrap(wsr.read()); const beat = JSON.parse(data); if (!beat.obsolete && beat.id !== this.head.id && beat.number >= this.head.number) { this.head = { id: beat.id, number: beat.number, timestamp: beat.timestamp, parentID: beat.parentID, txsFeatures: beat.txsFeatures, gasLimit: beat.gasLimit }; if (beat.baseFeePerGas) { this.head.baseFeePerGas = beat.baseFeePerGas; } this.cache.handleNewBlock(this.head, { k: beat.k, bits: beat.bloom }); this.emitNewHead(); } } } finally { wsr.close(); } }); } } exports.DriverNoVendor = DriverNoVendor; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJpdmVyLW5vLXZlbmRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9kcml2ZXItbm8tdmVuZG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUFBLDZDQUF3QztBQUN4QyxtQ0FBK0I7QUFDL0IscUNBQWdDO0FBRWhDLHVDQUFxRDtBQUVyRCx1RUFBdUU7QUFDdkUsTUFBYSxjQUFjO0lBU3ZCLFlBQ3VCLEdBQVEsRUFDbEIsT0FBMEIsRUFDbkMsV0FBd0M7UUFGckIsUUFBRyxHQUFILEdBQUcsQ0FBSztRQUNsQixZQUFPLEdBQVAsT0FBTyxDQUFtQjtRQVIvQixrQkFBYSxHQUFHLEVBQXVCLENBQUE7UUFDOUIsUUFBRyxHQUFHLElBQUksaUJBQU8sRUFBRSxDQUFBO1FBQ25CLFVBQUssR0FBRyxJQUFJLGFBQUssRUFBRSxDQUFBO1FBQ3BDLGdEQUFnRDtRQUMvQixvQkFBZSxHQUFpQyxFQUFFLENBQUE7UUFPL0QsSUFBSSxXQUFXLEVBQUU7WUFDYixJQUFJLENBQUMsSUFBSSxHQUFHLFdBQVcsQ0FBQTtTQUMxQjthQUFNO1lBQ0gsSUFBSSxDQUFDLElBQUksR0FBRztnQkFDUixFQUFFLEVBQUUsT0FBTyxDQUFDLEVBQUU7Z0JBQ2QsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNO2dCQUN0QixTQUFTLEVBQUUsT0FBTyxDQUFDLFNBQVM7Z0JBQzVCLFFBQVEsRUFBRSxPQUFPLENBQUMsUUFBUTtnQkFDMUIsV0FBVyxFQUFFLE9BQU8sQ0FBQyxXQUFXO2dCQUNoQyxRQUFRLEVBQUUsT0FBTyxDQUFDLFFBQVE7YUFDN0IsQ0FBQTtZQUNELElBQUksT0FBTyxDQUFDLGFBQWEsRUFBRTtnQkFDdkIsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQTthQUNsRDtTQUNKO1FBQ0QsS0FBSyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUE7SUFDL0IsQ0FBQztJQUVELHVDQUF1QztJ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