@meterio/flex-framework
Version:
A library implements Meter Flex interface
356 lines • 27.6 kB
JavaScript
"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.Cache = void 0;
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.jailedsUpdatedHeight = 0;
this.jaileds = [];
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(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;
});
}
getJaileds(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.jailedsUpdatedHeight) {
return this.jaileds;
}
}
let jailedList = yield fetch();
if (jailedList) {
this.jaileds = jailedList;
this.jailedsUpdatedHeight = currHeight;
}
return jailedList;
});
}
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(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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZHJpdmVyL2NhY2hlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUFBLGlDQUFpQztBQUNqQyxzREFBbUQ7QUFDbkQsK0NBQXFDO0FBRXJDLE1BQU0sVUFBVSxHQUFHLEVBQUUsQ0FBQztBQVl0QixNQUFhLEtBQUs7SUFBbEI7UUFDbUIsaUJBQVksR0FBRztZQUM5QixNQUFNLEVBQUUsSUFBSSxHQUFHLENBQW9DLEdBQUcsQ0FBQztZQUN2RCxHQUFHLEVBQUUsSUFBSSxHQUFHLENBQWlDLEdBQUcsQ0FBQztZQUNqRCxRQUFRLEVBQUUsSUFBSSxHQUFHLENBQTZCLEdBQUcsQ0FBQztTQUNuRCxDQUFDO1FBQ2UsV0FBTSxHQUFXLEVBQUUsQ0FBQztRQUU3Qiw0QkFBdUIsR0FBVyxDQUFDLENBQUM7UUFDcEMsZUFBVSxHQUEyQixFQUFFLENBQUM7UUFDeEMseUJBQW9CLEdBQVcsQ0FBQyxDQUFDO1FBQ2pDLFlBQU8sR0FBd0IsRUFBRSxDQUFDO1FBQ2xDLDhCQUF5QixHQUFXLENBQUMsQ0FBQztRQUN0QyxpQkFBWSxHQUE2QixFQUFFLENBQUM7UUFDNUMseUJBQW9CLEdBQVcsQ0FBQyxDQUFDO1FBQ2pDLFlBQU8sR0FBd0IsRUFBRSxDQUFDO1FBQ2xDLHlCQUFvQixHQUFXLENBQUMsQ0FBQztRQUNqQyxZQUFPLEdBQThCLElBQUksQ0FBQztRQUMxQyxrQ0FBNkIsR0FBVyxDQUFDLENBQUM7UUFDMUMscUJBQWdCLEdBQWdDLEVBQUUsQ0FBQztJQWdWN0QsQ0FBQztJQTlVUSxjQUFjLENBQ25CLElBQStCLEVBQy9CLEtBQW1DLEVBQ25DLEtBQXdCO1FBRXhCLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQzdCLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFN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