Skip to content

Commit

Permalink
docs(pkg/triedb): Add trieDB readme (#4103)
Browse files Browse the repository at this point in the history
  • Loading branch information
dimartiro authored Aug 22, 2024
1 parent 76741e4 commit a6b42f5
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 0 deletions.
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,30 @@ Then start the three hosts:
./bin/gossamer --chain westend-local --charlie
```

## Standalone Packages

In addition to the core functionality provided by Gossamer, we have developed some standalone packages that can be used independently. These packages are located in the `pkg` directory and serve various utility purposes. Here’s an overview of some of these packages:

### Scale

To support parity's [scale type encoding](https://docs.substrate.io/reference/scale-codec/) in golang.
More details [here](./pkg/scale/README.md)

### Trie

The `trie` package includes multiple implementations of polkadot merkle tries. These implementations are useful for various applications requiring efficient data structures. Here are the key implementations:

#### In-Memory Trie

This implementation supports polkadot merkle tries that are stored entirely in memory. It includes features for backing up the trie using a database to ensure persistence.

#### TrieDB

An evolution of the in-memory trie, `TrieDB` introduces lazy loading capabilities from the underlying database. This approach optimizes performance and resource usage by loading data only as needed.

For more details on how to use `TrieDB`, refer to the specific [README](pkg/trie/triedb/README.md)


## Contribute

- Check out the [Contributing Guidelines](.github/CONTRIBUTING.md) and our
Expand Down
114 changes: 114 additions & 0 deletions pkg/trie/triedb/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# trieDB


`triedb` is a library that acts as a layer over a key-value database, formatting those data into a radix-16 trie compatible with [polkadot spec](https://spec.polkadot.network/chap-state#sect-state-storage).
It offers functionalities for writing and reading operations and uses lazy loading to fetch data from the database, as well as a caching system to optimize searches.

## Main features

- **Writes**: Basic functions to manipulate data in the trie.
- **Reads**: Basic functions to get data from the trie.
- **Lazy Loading**: Load data on demand.
- **Caching**: Enhances search performance.
- **Compatibility**: Works with any database implementing the `db.RWDatabase` interface and any cache implementing the `cache.TrieCache` interface.
- **Merkle proofs**: Create and verify merkle proofs.
- **Iterator**: Traverse the trie keys in order.

## Usage

### Create a Trie

To create an empty trie:

```go
trie := triedb.NewEmptyTrieDB(db)
```

### Insert Data

To insert a key and its associated value:

```go
err := trie.Put([]byte("key"), []byte("value"))
```

### Get Data

To get the value associated with a key:

```go
value := trie.Get([]byte("key"))
```

> Note: value will be empty `[]byte()` if there is no value for that key in the DB

### Remove Data

To delete a key and its associated value:

```go
trie.Delete([]byte("key"))
```

### Commit Data

All modifications happen in memory until a commit is applied to the database. The commit is automatically applied whenever the root hash of the trie is calculated using:

```go
rootHash, err := trie.Hash()
if err != nil {
// handle error
}
```

or

```go
rootHash := trie.MustHash()
```

### Create a merkle proof

To create a merkle proof you will need a `db` previously created using a trie, the `trieVersion` (v0, v1), the `rootHash` for the trie in that db and an slice of `keys` for which the proof will be created.

```go
merkleProof, err := proof.NewMerkleProof(db, trieVersion, rootHash, keys)
```

### Verify merkle proofs

In order to verify a merkle proof you can execute the `Verify` method over a previously created proof specifying the `trieVersion`, `rootHash` and the `items` you want to check, doing the following:

```go
err = merkleProof.Verify(trieVersion, rootHash, items)
if err != nil {
fmt.Println("Invalid proof")
}
```

> Note: items is a slice of `proofItem` structure.
### Iterator

There are two ways to use the key iterator.
Iterating by keys

```go
trieIterator := triedb.NewTrieDBIterator(trie)

for key := iter.NextKey(); key != nil; key = iter.NextKey() {
fmt.Printf("key: %s", key)
}
```

Iterating by entries

```go
trieIterator := triedb.NewTrieDBIterator(trie)

for entry := iter.NextEntry(); entry != nil; entry = iter.NextEntry() {
fmt.Printf("key: %s, value: %s", entry.Key, entry.Value)
}
```

0 comments on commit a6b42f5

Please sign in to comment.