merkle-patricia-tree
Version:
This is an implementation of the modified merkle patricia tree as specified in Ethereum's yellow paper.
86 lines (76 loc) • 2.12 kB
text/typescript
// eslint-disable-next-line implicit-dependencies/no-implicit
import type { LevelUp } from 'levelup'
const level = require('level-mem')
export const ENCODING_OPTS = { keyEncoding: 'binary', valueEncoding: 'binary' }
export type BatchDBOp = PutBatch | DelBatch
export interface PutBatch {
type: 'put'
key: Buffer
value: Buffer
}
export interface DelBatch {
type: 'del'
key: Buffer
}
/**
* DB is a thin wrapper around the underlying levelup db,
* which validates inputs and sets encoding type.
*/
export class DB {
_leveldb: LevelUp
/**
* Initialize a DB instance. If `leveldb` is not provided, DB
* defaults to an [in-memory store](https://github.com/Level/memdown).
* @param leveldb - An abstract-leveldown compliant store
*/
constructor(leveldb?: LevelUp) {
this._leveldb = leveldb ?? level()
}
/**
* Retrieves a raw value from leveldb.
* @param key
* @returns A Promise that resolves to `Buffer` if a value is found or `null` if no value is found.
*/
async get(key: Buffer): Promise<Buffer | null> {
let value = null
try {
value = await this._leveldb.get(key, ENCODING_OPTS)
} catch (error: any) {
if (error.notFound) {
// not found, returning null
} else {
throw error
}
}
return value
}
/**
* Writes a value directly to leveldb.
* @param key The key as a `Buffer`
* @param value The value to be stored
*/
async put(key: Buffer, val: Buffer): Promise<void> {
await this._leveldb.put(key, val, ENCODING_OPTS)
}
/**
* Removes a raw value in the underlying leveldb.
* @param keys
*/
async del(key: Buffer): Promise<void> {
await this._leveldb.del(key, ENCODING_OPTS)
}
/**
* Performs a batch operation on db.
* @param opStack A stack of levelup operations
*/
async batch(opStack: BatchDBOp[]): Promise<void> {
await this._leveldb.batch(opStack, ENCODING_OPTS)
}
/**
* Returns a copy of the DB instance, with a reference
* to the **same** underlying leveldb instance.
*/
copy(): DB {
return new DB(this._leveldb)
}
}