LogoLogo
  • Introduction
  • Quick Start
  • ⭕HollowDB
    • Usage
    • Supported Wallets
    • Modes of Operation
    • Usage with Bundlr
    • Contract Operations
    • Caching Options
    • HollowDB-as-a-Service
  • 🔐Zero-Knowledge Proofs
    • Background
    • HollowDB Authentication
    • HollowDB Prover
    • Usage with Proofs
    • Proofs from Signatures
  • ⚒️Use-Cases
    • 👀Overview
    • 📆Calendar
    • 🔓Anonymous Authentication
    • 👤Persona
Powered by GitBook
On this page
  • LMDB Cache
  • Redis Cache
  1. HollowDB

Caching Options

Optional caching with LMDB or Redis.

PreviousContract OperationsNextHollowDB-as-a-Service

Last updated 1 year ago

Warp uses LevelDB on Node and IndexedDB on browser for caching by default. It allows overriding the cache to be used via useStateCache and useContractCache; as well as overriding the underlying key-value storage via useKVStorageFactory. These overrides accept any cache interface that supports the of Warp Contracts, see the relevant documentation .

Since HollowDB takes input a warp instance, by applying cache overrides to the warp instance outside and passing that instance to HollowDB, you will be able to use the caching of your choice for HollowDB!

LMDB is an ultra-fast NodeJS, Bun, and Deno interface to LMDB; probably the fastest and most efficient key-value/database interface that exists for storage and retrieval of structured JS data (objects, arrays, etc.) in a true persisted, scalable, database

Warp Contracts provide an LMDB cache interface under package. It can used as follows:

import {defaultCacheOptions, WarpFactory} from 'warp-contracts';
import {LmdbCache} from 'warp-contracts-lmdb';

warp = WarpFactory
  .forMainnet()
  .useStateCache(
    new LmdbCache(
      {
        ...defaultCacheOptions,
        dbLocation: './cache/warp/state',
      }
    )
  )
  .useContractCache(
    new LmdbCache({
      ...defaultCacheOptions,
      dbLocation: './cache/warp/contract',
    }),
    new LmdbCache({
      ...defaultCacheOptions,
      dbLocation: './cache/warp/src',
    })
  )
  .useKVStorageFactory(
    (contractTxId: string) =>
      new LmdbCache({
        ...defaultCacheOptions,
        dbLocation: `./cache/warp/kv/lmdb_2/${contractTxId}`,
      })
  );
import {WarpFactory, CacheOptions} from 'warp-contracts';
import {RedisCache, RedisOptions} from 'warp-contracts-redis';

// in case you might use this Redis for multiple contracts,
// it might be best to have a different key for each contract!
const contractTxId = "your-contract-tx-id";

const cacheOptions: CacheOptions = {
  inMemory: true,
  subLevelSeparator: "|",
  dbLocation: "", // we will override this
};
const redisOptions: RedisOptions = {
  url: constants.REDIS_URL,
};
warp = warp
  .forMainnet()
  .useStateCache(
    new RedisCache(
      {
        ...cacheOptions,
        dbLocation: `${contractTxId}.state`,
      },
      redisOptions
    )
  )
  .useContractCache(
    new RedisCache(
      {
        ...cacheOptions,
        dbLocation: `${contractTxId}.contract`,
      },
      redisOptions
    ),
    new RedisCache(
      {
        ...cacheOptions,
        dbLocation: `${contractTxId}.src`,
      },
      redisOptions
    )
  )
  .useKVStorageFactory(
    (contractTxId: string) =>
      new RedisCache(
        {
          ...cacheOptions,
          dbLocation: `${contractTxId}.kv`,
        },
        redisOptions
      )
  );

Redis is not exactly like the other cache options (LMDB or the default LevelDB) which are "local". In the case of Redis, we can host a Redis server and connect to it, thereby solving the problem of downloading the entire state on different machines each time. We can also use the same client on multiple cache types, for example a single Redis client in our application can be used for state cache, contract cache and kv-cache at once.

// create client
const redisClient = new Redis("connection url", {lazyConnect: true});

// pass the client in constructor
warp = warp
  .useKVStorageFactory(
    (contractTxId: string) =>
      new RedisCache({
          ...cacheOptions,
          dbLocation: `${contractTxId}.kv`,
        },
        { client: redisClient }
      )
  );

// define custom scripts used by RedisCache
RedisCache.defineLuaScripts(client);

// connect to client manually
await redisClient.connect();

// optional: disable persistent memory
// this is what `inMemory: true` normally does
await Redis.setConfigForInMemory(client);

The extra steps in the end are normally done internally, but to avoid repeating them in consequent usages of the same client, we expect the user to take the responsibility of doing them. A warning log also notifies the user of this at runtime.

Redis is an open source (BSD licensed), in-memory data structure store used as a database, cache, message broker, and streaming engine. Redis provides such as , , , , with range queries, , , , and .

We have prepared a Redis SortKeyCache implementation under . It can be used as follows:

For this purpose, we allow the user to create the client outside, and pass it to the RedisCache in the constructor. Here is an example using package for the client.

⭕
SortKeyCache interface
here
LMDB Cache
ACID compliant
warp-contracts-lmdb
Redis Cache
data structures
strings
hashes
lists
sets
sorted sets
bitmaps
hyperloglogs
geospatial indexes
streams
warp-contracts-redis
ioredis