UNPKG

simonflex-framework

Version:

A library implements Meter Flex interface

334 lines 26 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const LRU = require("lru-cache"); const bloom_1 = require("@meterio/devkit/dist/bloom"); const bignumber_js_1 = require("bignumber.js"); const WINDOW_LEN = 12; class Cache { constructor() { this.irreversible = { blocks: new LRU(256), txs: new LRU(512), receipts: new LRU(512), }; this.window = []; this.candidatesUpdatedHeight = 0; this.candidates = []; this.bucketsUpdatedHeight = 0; this.buckets = []; this.stakeholdersUpdatedHeight = 0; this.stakeholders = []; this.auctionUpdatedHeight = 0; this.auction = null; this.auctionSummariesUpdatedHeight = 0; this.auctionSummaries = []; } handleNewBlock(head, bloom, block) { while (this.window.length > 0) { const top = this.window[this.window.length - 1]; if (top.id === head.id) { return; } if (top.id === head.parentID) { break; } this.window.pop(); } this.window.push(Object.assign({}, head, { bloom: bloom ? new bloom_1.Bloom(bloom.k, Buffer.from(bloom.bits.slice(2), 'hex')) : undefined, block, accounts: new Map(), txs: new Map(), receipts: new Map(), tied: new Map() })); // shift out old slots and move cached items into frozen cache while (this.window.length > WINDOW_LEN) { const bottom = this.window.shift(); bottom.txs.forEach((v, k) => this.irreversible.txs.set(k, v)); bottom.receipts.forEach((v, k) => this.irreversible.receipts.set(k, v)); if (bottom.block) { this.irreversible.blocks.set(bottom.block.id, bottom.block); this.irreversible.blocks.set(bottom.block.number, bottom.block); } } } getBlock(revision, fetch) { return __awaiter(this, void 0, void 0, function* () { let block = this.irreversible.blocks.get(revision) || null; if (block) { return block; } const { slot } = this.findSlot(revision); if (slot && slot.block) { return slot.block; } block = yield fetch(); if (block) { if (slot && slot.id === block.id) { slot.block = block; } if (this.isIrreversible(block.number)) { this.irreversible.blocks.set(block.id, block); if (block.isTrunk) { this.irreversible.blocks.set(block.number, block); } } } return block; }); } getCandidates(fetch) { return __awaiter(this, void 0, void 0, function* () { let currHeight = 0; if (this.window.length > 0) { const top = this.window[this.window.length - 1]; currHeight = top.number; if (top.number <= this.candidatesUpdatedHeight) { return this.candidates; } } let candidateList = yield fetch(); if (candidateList) { this.candidates = candidateList; this.candidatesUpdatedHeight = currHeight; } return candidateList; }); } getBuckets(fetch) { return __awaiter(this, void 0, void 0, function* () { let currHeight = 0; if (this.window.length > 0) { const top = this.window[this.window.length - 1]; currHeight = top.number; if (top.number <= this.bucketsUpdatedHeight) { return this.buckets; } } let bucketList = yield fetch(); if (bucketList) { this.buckets = bucketList; this.bucketsUpdatedHeight = currHeight; } return bucketList; }); } getStakeholders(fetch) { return __awaiter(this, void 0, void 0, function* () { let currHeight = 0; if (this.window.length > 0) { const top = this.window[this.window.length - 1]; currHeight = top.number; if (top.number <= this.stakeholdersUpdatedHeight) { return this.stakeholders; } } let stakeholderList = yield fetch(); if (stakeholderList) { this.stakeholders = stakeholderList; this.stakeholdersUpdatedHeight = currHeight; } return stakeholderList; }); } getAuction(fetch) { return __awaiter(this, void 0, void 0, function* () { let currHeight = 0; if (this.window.length > 0) { const top = this.window[this.window.length - 1]; currHeight = top.number; if (top.number <= this.auctionUpdatedHeight) { if (this.auction != null) { return this.auction; } } } let curAuction = yield fetch(); if (curAuction) { this.auction = curAuction; this.auctionUpdatedHeight = currHeight; } return curAuction; }); } getAuctionSummaries(fetch) { return __awaiter(this, void 0, void 0, function* () { let currHeight = 0; if (this.window.length > 0) { const top = this.window[this.window.length - 1]; currHeight = top.number; if (top.number <= this.auctionSummariesUpdatedHeight) { return this.auctionSummaries; } } let summaries = yield fetch(); if (summaries) { this.auctionSummaries = summaries; this.auctionSummariesUpdatedHeight = currHeight; } return summaries; }); } getTx(txid, fetch) { return __awaiter(this, void 0, void 0, function* () { let tx = this.irreversible.txs.get(txid) || null; if (tx) { return tx; } for (const slot of this.window) { tx = slot.txs.get(txid) || null; if (tx) { return tx; } } tx = yield fetch(); if (tx) { const { slot } = this.findSlot(tx.meta.blockID); if (slot) { slot.txs.set(txid, tx); } if (this.isIrreversible(tx.meta.blockNumber)) { this.irreversible.txs.set(txid, tx); } } return tx; }); } getReceipt(txid, fetch) { return __awaiter(this, void 0, void 0, function* () { let receipt = this.irreversible.receipts.get(txid) || null; if (receipt) { return receipt; } for (const slot of this.window) { receipt = slot.receipts.get(txid) || null; if (receipt) { return receipt; } } receipt = yield fetch(); if (receipt) { const { slot } = this.findSlot(receipt.meta.blockID); if (slot) { slot.receipts.set(txid, receipt); } if (this.isIrreversible(receipt.meta.blockNumber)) { this.irreversible.receipts.set(txid, receipt); } } return receipt; }); } getAccount(addr, revision, fetch) { return __awaiter(this, void 0, void 0, function* () { const found = this.findSlot(revision); for (let i = found.index; i >= 0; i--) { const slot = this.window[i]; const acc = slot.accounts.get(addr); if (acc) { if (i !== found.index) { found.slot.accounts.set(addr, acc); } return acc.snapshot(found.slot.timestamp); } if (!slot.bloom || testBytesHex(slot.bloom, addr)) { // account might be dirty break; } } const accObj = yield fetch(); if (found.slot) { found.slot.accounts.set(addr, new Account(accObj, found.slot.timestamp)); } return accObj; }); } /** * get cached entry which is tied to a batch of addresses * @param key the cache key * @param revision block id where cache bound to * @param fetch to fetch value when cache missing * @param ties array of tied addresses, as the gist to invalidate cache key. undefined means the key is always * invalidated on different revision. */ getTied(key, revision, fetch, ties) { return __awaiter(this, void 0, void 0, function* () { const found = this.findSlot(revision); for (let i = found.index; i >= 0; i--) { const slot = this.window[i]; const v = slot.tied.get(key); if (v) { if (i !== found.index) { found.slot.tied.set(key, v); } return v; } if (!slot.bloom || !ties) { break; } // if ties.length === 0, never invalidate cache if (ties.some((t) => testBytesHex(slot.bloom, t))) { // might be dirty break; } } const value = yield fetch(); if (found.slot) { found.slot.tied.set(key, value); } return value; }); } findSlot(revision) { const index = this.window.findIndex((s) => s.id === revision || s.number === revision); if (index >= 0) { return { slot: this.window[index], index }; } return { index }; } isIrreversible(n) { if (this.window.length > 0) { return n < this.window[this.window.length - 1].number - WINDOW_LEN; } return false; } } exports.Cache = Cache; function testBytesHex(bloom, hex) { let buf = Buffer.from(hex.slice(2), 'hex'); const nzIndex = buf.findIndex((v) => v !== 0); if (nzIndex < 0) { buf = Buffer.alloc(0); } else { buf = buf.slice(nzIndex); } return bloom.test(buf); } const ENERGY_GROWTH_RATE = 5000000000; class Account { constructor(obj, initTimestamp) { this.obj = obj; this.initTimestamp = initTimestamp; } snapshot(timestamp) { return Object.assign({}, this.obj, { energy: this.energyAt(timestamp) }); } energyAt(timestamp) { if (timestamp < this.initTimestamp) { return this.obj.energy; } return ('0x' + new bignumber_js_1.default(this.obj.balance) .times(timestamp - this.initTimestamp) .times(ENERGY_GROWTH_RATE) .dividedToIntegerBy(1e18) .plus(this.obj.energy) .toString(16)); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZHJpdmVyL2NhY2hlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQSxpQ0FBaUM7QUFDakMsc0RBQW1EO0FBQ25ELCtDQUFxQztBQUVyQyxNQUFNLFVBQVUsR0FBRyxFQUFFLENBQUM7QUFZdEIsTUFBYSxLQUFLO0lBQWxCO1FBQ21CLGlCQUFZLEdBQUc7WUFDOUIsTUFBTSxFQUFFLElBQUksR0FBRyxDQUFvQyxHQUFHLENBQUM7WUFDdkQsR0FBRyxFQUFFLElBQUksR0FBRyxDQUFpQyxHQUFHLENBQUM7WUFDakQsUUFBUSxFQUFFLElBQUksR0FBRyxDQUE2QixHQUFHLENBQUM7U0FDbkQsQ0FBQztRQUNlLFdBQU0sR0FBVyxFQUFFLENBQUM7UUFFN0IsNEJBQXVCLEdBQVcsQ0FBQyxDQUFDO1FBQ3BDLGVBQVUsR0FBMkIsRUFBRSxDQUFDO1FBQ3hDLHlCQUFvQixHQUFXLENBQUMsQ0FBQztRQUNqQyxZQUFPLEdBQXdCLEVBQUUsQ0FBQztRQUNsQyw4QkFBeUIsR0FBVyxDQUFDLENBQUM7UUFDdEMsaUJBQVksR0FBNkIsRUFBRSxDQUFDO1FBQzVDLHlCQUFvQixHQUFXLENBQUMsQ0FBQztRQUNqQyxZQUFPLEdBQThCLElBQUksQ0FBQztRQUMxQyxrQ0FBNkIsR0FBVyxDQUFDLENBQUM7UUFDMUMscUJBQWdCLEdBQWdDLEVBQUUsQ0FBQztJQTZUN0QsQ0FBQztJQTNUUSxjQUFjLENBQ25CLElBQStCLEVBQy9CLEtBQW1DLEVBQ25DLEtBQXdCO1FBRXhCLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQzdCLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDaEQsSUFBSSxHQUFHLENBQUMsRUFBRSxLQUFLLElBQUks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