orbitdb / orbitdb

Peer-to-Peer Databases for the Decentralized Web

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can't open existing database

lakexyde opened this issue · comments

I am not able to open an existing database, I keep getting the following error:
AggregateError: All promises were rejected
Creating e new database works fine but I can't reopen it with the same address. Any idea on how to fix this?

You may need to close the db and also explicitly close the underlying leveldb. Can you share a code example?

You may need to close the db and also explicitly close the underlying leveldb. Can you share a code example?

Here's the code sample below:

const Libp2pOptions = {
  services: {
    pubsub: gossipsub({
      // neccessary to run a single peer
      allowPublishToZeroPeers: true
    }),
    identify: identify()
  }
}

class AppDB {

  orbitdb;
  ipfs;

  async init() {

    try {

      const entropy = bip39.mnemonicToEntropy("seed_phrase_here");
      const seed = Buffer.from(entropy, 'hex');

      OrbitDBIdentityProviderDID.setDIDResolver(KeyDidResolver.getResolver())
      useIdentityProvider(OrbitDBIdentityProviderDID)
      const didProvider = new Ed25519Provider(seed)
      const provider = OrbitDBIdentityProviderDID({ didProvider });

      const libp2p = await createLibp2p({ ...Libp2pOptions })
      this.ipfs = await createHelia({ libp2p })

      const identities = await Identities({ ipfs: this.ipfs });
      const identity = await identities.createIdentity({ provider })

      this.orbitdb = await createOrbitDB({ ipfs: this.ipfs, identities, identity });

      console.log("Done initialising node");

    } catch (error) {
      console.log("ERROR", error);
    }
  }

  async close() {
    await this.ipfs?.stop();
    await this.orbitdb?.stop()
  }

  async open(address) {

    try {
      const db = await this.orbitdb.open(address);
      console.log("DATABASE: ", db);
      console.log(await db.all());
    } catch (error) {
      console.log("Error opening database: ", error)
    }
  }
}

Thank you.

Thanks. Can you provide a full working copy which I can run and that demonstrates the problem?

Thanks. Can you provide a full working copy which I can run and that demonstrates the problem?

import { createHelia } from 'helia'
import { createOrbitDB, useIdentityProvider, Identities, useAccessController } from '@orbitdb/core'
import { gossipsub } from "@chainsafe/libp2p-gossipsub";
import { identify } from "@libp2p/identify";
import { createLibp2p } from 'libp2p'
import * as bip39 from 'bip39'
import OrbitDBIdentityProviderDID from '@orbitdb/identity-provider-did'
import KeyDidResolver from 'key-did-resolver'
import { Ed25519Provider } from 'key-did-provider-ed25519'

const Libp2pOptions = {
  services: {
    pubsub: gossipsub({
      // neccessary to run a single peer
      allowPublishToZeroPeers: true
    }),
    identify: identify()
  }
}

class AppDB {

  orbitdb;
  ipfs;

  async init() {

    try {

      const entropy = bip39.mnemonicToEntropy("enter your seed phrase or generate one");
      const seed = Buffer.from(entropy, 'hex');

      OrbitDBIdentityProviderDID.setDIDResolver(KeyDidResolver.getResolver())
      useIdentityProvider(OrbitDBIdentityProviderDID)
      const didProvider = new Ed25519Provider(seed)
      const provider = OrbitDBIdentityProviderDID({ didProvider });

      const libp2p = await createLibp2p({ ...Libp2pOptions })
      this.ipfs = await createHelia({ libp2p })

      const identities = await Identities({ ipfs: this.ipfs });
      const identity = await identities.createIdentity({ provider })

      useAccessController(CustomAccessController)

      this.orbitdb = await createOrbitDB({ ipfs: this.ipfs, identities, identity });

      console.log("Done initialising node");

    } catch (error) {
      console.log("ERROR", error);
    }
  }

  async close() {
    await this.ipfs?.stop();
    await this.orbitdb?.stop()
  }

  async open(address) {

    try {
      const db = await this.orbitdb.open(address, { type: 'documents' });
      console.log("DATABASE ADDRESS: ", db.address);
      console.log(await db.all());
    } catch (error) {
      console.log("Error opening database: ", error)
    }
  }
}

async function main() {
  try {
    const db = new AppDB();

    // initialise database
    await db.init();

   // open a database
   await db.open("my-db")
  } catch (error) { console.log(error) }
}

main();

Running without a database address works fine, but using the address to open again return the error.
Thanks.

The problem is caused by not having a permanent blockstore in Helia (IPFS).

When you try and open the database by name, it will create it if it doesn't exist. If you try and open a database by address, it will attempt to retrieve the database from IPFS's blockstore. However because your blockstore is transient (I.e. it is only available in memory while your script is running), the blocks that make up your database are no longer available and so the open db times out with an error.

By adding a permanent blockstore, the "open db by address" is able to retrieve the blocks from the underlying IPFS blockstore.

If you add a permanent blockstore, this should solve your problem.

E.g.

Import the level blockstore:

import { LevelBlockstore } from 'blockstore-level'

Initialize it and pass it to Helia:

const blockstore = new LevelBlockstore('./ipfs/blocks')
this.ipfs = await createHelia({ libp2p, blockstore })

Hope this helps.

Thank you very much. Now working 💯