# Meaning of Kubo data store configuration with 2 mounts

**URL:** <https://discuss.ipfs.tech/t/meaning-of-kubo-data-store-configuration-with-2-mounts/15692>\
**Category:** Kubo\
**Created:** [December 14, 2022, 3:48pm UTC](https://discuss.ipfs.tech/t/meaning-of-kubo-data-store-configuration-with-2-mounts/15692 "2022-12-14T15:48:51Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![danieln](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ipfs.tech/danieln/32/6408_2.png) [@danieln](https://discuss.ipfs.tech/u/danieln)\
**Post date:** [December 14, 2022, 3:48pm UTC](https://discuss.ipfs.tech/t/meaning-of-kubo-data-store-configuration-with-2-mounts/15692/1 "2022-12-14T15:48:51Z")

</div>

My `/.ipfs/datastore_spec` file looks as follows

```auto
{
  "mounts": [
    {
      "mountpoint": "/blocks",
      "path": "blocks",
      "shardFunc": "/repo/flatfs/shard/v1/next-to-last/2",
      "type": "flatfs"
    },
    {
      "mountpoint": "/",
      "path": "datastore",
      "type": "levelds"
    }
  ],
  "type": "mount"
}

```

What is the meaning of the two mounts?

What is the relationship between `levelsds` and `flatfs`?

Is this documented anywhere?

The datastore docs [kubo/datastores.md at master · ipfs/kubo · GitHub](https://github.com/ipfs/kubo/blob/master/docs/datastores.md) are mostly concerned with the individual stores but not with how it works with multiple mounts.

---

<div class="post-metadata">

**Author:** ![Jorropo](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ipfs.tech/jorropo/32/3230_2.png) [@Jorropo](https://discuss.ipfs.tech/u/Jorropo)\
**Post date:** [December 14, 2022, 3:57pm UTC](https://discuss.ipfs.tech/t/meaning-of-kubo-data-store-configuration-with-2-mounts/15692/2 "2022-12-14T15:57:52Z")

</div>

Kubo has two internal DB types:

1. Blockstore, this store blocks, it is what flatfs implements
2. Datastore, this is a normal KV store, it is what levelds implements.

We have some wrapper that implements blockstore over datastore, this is used when you use badger (badger implements datastore and we use the wrapper to store blocks through badger’s datastore).  
In theory you could use leveldb in the same way but if it’s not being done I guess that perfs aren’t that great.

Note: we can’t just rely on a blockstore because we need something else to store various metadata (what you have pinned, the MFS root, …)

---

<div class="post-metadata">

**Author:** ![danieln](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ipfs.tech/danieln/32/6408_2.png) [@danieln](https://discuss.ipfs.tech/u/danieln)\
**Post date:** [December 14, 2022, 4:41pm UTC](https://discuss.ipfs.tech/t/meaning-of-kubo-data-store-configuration-with-2-mounts/15692/3 "2022-12-14T16:41:26Z")

</div>

So if I understand it correctly:

1. Blockstore stores raw blocks
2. Datastore is used to store metadata (what you have pinned, MFS root)

What is the main difference between them? Does the datastore store things in a structured way that allows fast querying

* * *

Since Badger, by default, implements the Datastore interface, you use this wrapper so you can use it as a blockstore.

This begs the question: when using Badger, is it used as both a blockstore **and** datastore?

---

<div class="post-metadata">

**Author:** ![Jorropo](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ipfs.tech/jorropo/32/3230_2.png) [@Jorropo](https://discuss.ipfs.tech/u/Jorropo)\
**Post date:** [December 14, 2022, 5:00pm UTC](https://discuss.ipfs.tech/t/meaning-of-kubo-data-store-configuration-with-2-mounts/15692/4 "2022-12-14T17:00:56Z")

</div>

> Datastore is used to store metadata (what you have pinned, MFS root)

datastore does not store metadata, it stores anything that KV and we could need it for.

> What is the main difference between them? Does the datastore store things in a structured way that allows fast querying

No not really, _we could_ but we don’t.

This is mainly a type difference and helps make the code clearer, it’s mostly looking like this (pseudo code):

```go
type Blockstore interface{
  Get(m mh.Multihash) ([]byte, error)
  Put(m mh.Multihash, b []byte) error
}

type Datastore interface{
  Get(k string) ([]byte, error)
  Put(k string, b []byte) error
}

type DatastoreToBlockstoreWrapper struct{
  d Datastore
  preffix string
  hashOnRead bool
}

func (w DatastoreToBlockstoreWrapper) Get(m mh.Multihash) ([]byte, error) {
  data, err := w.Datastore.Get(w.mhToKey(m))
  if err != nil {
    return nil, err
  }
  if w.hashOnRead {
    sum := m.Header().Sum(data)
    if sum != m {
      return nil, errors.New("red data doesn't match expected hash")
    }
  }
  return data, nil
}

func (w DatastoreToBlockstoreWrapper) Put(m mh.Multihash, b []byte) error {
  return w.Datastore.Put(w.mhToKey(m), b)
}

func (w DatastoreToBlockstoreWrapper) mhToKey(m mh.Multihash) string {
  return "/blockstore/" + w.pref + "/" + string(m)
}

```

One of them is a bytes to bytes mapping (datastore), one of them is multihash to bytes (blockstore).

> This begs the question: when using Badger, is it used as both a blockstore **and** datastore?

Yes but not really.  
Yes in practice it’s true, however badger does not know that, badger is just mapping keys to bytes “dumbly”.

Here are the actual interfaces:

- `Datastore` [datastore package - github.com/ipfs/go-datastore - Go Packages](https://pkg.go.dev/github.com/ipfs/go-datastore#Datastore)
- `Blockstore` [blockstore package - github.com/ipfs/go-ipfs-blockstore - Go Packages](https://pkg.go.dev/github.com/ipfs/go-ipfs-blockstore#Blockstore) (I know the interface use CIDs and not multihash, this is _history_, since Kubo 0.12 and multihash keying, we unwrap the CID and just use the multihash)

---

<div class="post-metadata">

**Author:** ![teiresias](https://avatars.discourse-cdn.com/v4/letter/t/13edae/32.png) [@teiresias](https://discuss.ipfs.tech/u/teiresias)\
**Post date:** [December 14, 2022, 5:08pm UTC](https://discuss.ipfs.tech/t/meaning-of-kubo-data-store-configuration-with-2-mounts/15692/5 "2022-12-14T17:08:19Z")

</div>

> What is the main difference between them? Does the datastore store things in  
> a structured way that allows fast querying

The block store is just a Unix directory tree. It’s sharded, so you  
don’t have a million files in one single directory or whatever.

The data store is a key-value store. The keys are structured. Think  
on-disk dictionary. For instance, the CID of your local MFS root is  
stored in the datastore under the key /local/filesroot. It’s fast.

---

<div class="post-metadata">

**Author:** ![Jorropo](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ipfs.tech/jorropo/32/3230_2.png) [@Jorropo](https://discuss.ipfs.tech/u/Jorropo)\
**Post date:** [December 14, 2022, 5:10pm UTC](https://discuss.ipfs.tech/t/meaning-of-kubo-data-store-configuration-with-2-mounts/15692/6 "2022-12-14T17:10:23Z")

</div>

> [@teiresias](#):
>
> The block store is just a Unix directory tree

this is an over generalisation assuming that all blockstores are flatfs.  
It’s how flatfs works, but not badgerdb.

Or whatever future sparse based blockstore I want to write.
