watcher-ts/packages/cache/src/cache.ts
Ashwin Phatak 7213a1dc6d
Lazy ERC20 watcher (#11)
* Storage mapping utils.

* Resolver factories.

* Get ERC20 balance from upstream ipld-eth-server slot.

* Get ERC20 allowance from storage slot.

* Parse ERC20 events from block events.

* Cache GQL requests in leveldb.

* Refactor fetch/cache from upstream into eth-loader class.

* Refactoring.

* Refactor eth-client, extract cache class.

* Cache config settings.

* Debug logs.

* Rename server to watcher.

* Start local server by default.

* Split into multiple packages.

* eth-client API methods.

* Update docs.
2021-05-28 16:56:40 +05:30

82 lines
1.6 KiB
TypeScript

import assert from 'assert';
import canonicalStringify from 'canonical-json';
import { ethers } from 'ethers';
import level from 'level';
import fs from 'fs-extra';
import path from 'path';
import debug from 'debug';
const log = debug('vulcanize:cache');
export const getCache = async (config) => {
let cache;
// Cache is optional.
if (config) {
log("config", JSON.stringify(config, null, 2));
const { name, enabled, deleteOnStart } = config;
assert(name);
const cacheDirPath = path.join(process.cwd(), 'out', `${name}.db`);
await fs.ensureDir(cacheDirPath);
// Delete cache on start.
if (deleteOnStart) {
await fs.emptyDir(cacheDirPath);
}
// Enable/disable flag for the cache.
if (enabled) {
cache = new Cache(name, cacheDirPath);
}
}
return cache;
};
export class Cache {
_db: any;
_name: string;
constructor(name, dirPath) {
assert(name);
assert(dirPath);
this._name = name;
this._db = level(dirPath, { valueEncoding: 'json' });;
}
key(obj) {
return this._cacheKey(obj);
}
async get(obj) {
const key = this._cacheKey(obj);
try {
const value = await this._db.get(key);
log(`${this._name}: cache hit ${key}`);
return [value, true];
} catch (err) {
log(`${this._name}: cache miss ${key}`);
if (err.notFound) {
return [undefined, false]
}
}
}
async put(obj, value) {
await this._db.put(this._cacheKey(obj), value);
}
_cacheKey(obj) {
return ethers.utils.keccak256(Buffer.from(canonicalStringify(obj)));
}
}