bdb (bcoin-org) - LevelDB Backend

1.6.2 · maintenance · verified Wed Apr 22

bdb is an embedded, low-level key-value database library specifically designed as a LevelDB backend for the bcoin full node Bitcoin implementation. It is built on top of `leveldown` (or compatible LevelDB bindings) to provide persistent storage. The package, currently at version 1.6.2, is part of the broader `bcoin-org` ecosystem, which appears to be under active maintenance, though `bdb` itself sees less frequent, direct updates. Its primary differentiator is the `bdb.key` utility, offering structured key encoding and decoding for managing complex data types common in blockchain applications, such as cryptographic hashes and integers, enabling efficient storage and retrieval. Unlike general-purpose LevelDB wrappers, `bdb` is tailored for the specific data structures and performance requirements of a Bitcoin node. It operates as a local, embedded database without a server component, similar to other NoSQL key-value stores. Release cadence is tied to the needs of the `bcoin` project, rather than independent frequent updates.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates opening a bdb database, creating a bucket, encoding/decoding structured keys, performing batch writes, and iterating over stored key-value pairs using both callback-based and async iterators, then properly closing and cleaning up the database.

const bdb = require('bdb');
const path = require('path');
const os = require('os');
const fs = require('fs/promises');

async function runDbExample() {
  const dbPath = path.join(os.tmpdir(), `bdb-example-${Date.now()}`);
  await fs.mkdir(dbPath, { recursive: true });
  
  const db = bdb.create(dbPath);

  try {
    await db.open();
    console.log('Database opened at:', dbPath);

    const myPrefix = bdb.key('r');
    const myKey = bdb.key('t', ['hash160', 'uint32']);

    const bucket = db.bucket(myPrefix.encode());
    const batch = bucket.batch();

    const hash = Buffer.alloc(20, 0x11); // Example 20-byte hash

    // Write `foo` to `rt[11...11][00000000]`
    batch.put(myKey.encode(hash, 0), Buffer.from('foo'));
    batch.put(myKey.encode(Buffer.alloc(20, 0x22), 1), Buffer.from('bar'));

    await batch.write();
    console.log('Batch write complete.');

    // Iterate:
    const iter = bucket.iterator({
      gte: myKey.min(),
      lte: myKey.max(),
      values: true
    });

    console.log('\nIterating through records:');
    await iter.each((key, value) => {
      const [decodedHash, index] = myKey.decode(key);
      console.log('  Key:', key.toString('hex'), '-> Hash:', decodedHash.toString('hex'), 'Index:', index, 'Value:', value.toString());
    });
    
    await iter.end(); // Important to close iterator resources

    // Using async iterator:
    console.log('\nIterating with async iterator:');
    const asyncIter = bucket.iterator({
      gte: myKey.min(),
      lte: myKey.max(),
      values: true
    });

    for await (const {key, value} of asyncIter) {
      const [decodedHash, index] = myKey.decode(key);
      console.log('  Key:', key.toString('hex'), '-> Hash:', decodedHash.toString('hex'), 'Index:', index, 'Value:', value.toString());
    }

    await db.close();
    console.log('\nDatabase closed.');
  } catch (error) {
    console.error('Database operation failed:', error);
  } finally {
    await fs.rm(dbPath, { recursive: true, force: true });
    console.log('Cleaned up database directory:', dbPath);
  }
}

runDbExample();

view raw JSON →