Skip to content

Commit

Permalink
Publish 2.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
KtorZ committed Sep 6, 2024
1 parent 8d8c703 commit 4506510
Show file tree
Hide file tree
Showing 26 changed files with 58 additions and 5,531 deletions.
119 changes: 57 additions & 62 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,69 +1,64 @@
<div align="center">
# Merkle Patricia Forestry

<h1 align="center">Merkle Patricia Forestry</h1>
<img alt="Merkle Patricia Forestry" src=".github/logo.png" height="250">
<p align="center" style="border-bottom: none">A set of (on-chain & off-chain) libraries for working with <strong>Merkle Patricia Tries</strong> on Cardano.</p>
This package provides an Aiken library for working with an authenticated key/value store: a.k.a [Merkle Patricia Forestry](../README.md). It comes with a [companion off-chain package](../off-chain) for generating proofs and actually maintaining the raw data-structure since on-chain, we only ever deal with hashes.

<hr/>
## Installation

[![Licence](https://img.shields.io/github/license/aiken-lang/merkle-patricia-forestry?style=for-the-badge)](https://github.com/aiken-lang/merkle-patricia-forestry/blob/main/LICENSE)
[![Continuous Integration](https://img.shields.io/github/actions/workflow/status/aiken-lang/merkle-patricia-forestry/continuous-integration.yml?style=for-the-badge&label=continuous%20integration)](https://github.com/aiken-lang/merkle-patricia-forestry/actions/workflows/continuous-integration.yml)
[![NPM](https://img.shields.io/npm/v/%40aiken-lang%2Fmerkle-patricia-forestry?style=for-the-badge)](https://www.npmjs.com/package/@aiken-lang/merkle-patricia-forestry)

<hr/>
</div>

## Overview

A Merkle Patricia Trie is a persistent & authenticated data structure to map between arbitrary keys and values. It's like a hashmap on steroids, which isn't tamperable. The items are represented in a space-optimized trie (a.k.a prefix tree) of radix 16. The hash digest of their keys gives the path to values in the trie. For more details, read [the wiki](https://github.com/aiken-lang/merkle-patricia-forestry/wiki/Technical-analysis).

The use cases are numerous, such as maintaining large on-chain registries (e.g. domains) or providing unreasonably large oracled datasets of intrinsic data (e.g. a map of delegators/delegatees) or extrinsic data (e.g. GitHub data pertaining to an ecosystem of projects). It's also perfectly suited for long-running datasets that grow at a _slow_ rate (e.g. a PoW blockchain).

### Features

Using only a root hash digest (32 bytes) and a succinct proof (<1KB), Merkle Patricia Tries provides rapid:

- [x] membership
- [x] insertion
- [x] deletion

...of any key/value item in a large (billions) store.

## Getting Started

### Off-chain (JavaScript / Node.js)

```bash
yarn add @aiken-lang/merkle-patricia-forestry
```

See [off-chain](./off-chain#readme) for usage.

### On-chain (Aiken)

```bash
aiken add --version 1.1.0 aiken-lang/merkle-patricia-forestry
aiken add aiken-lang/merkle-patricia-forestry --version 2.0.0
```

See [on-chain](./on-chain#readme) for usage.

## Performances

This library implements a few optimizations. We borrow ideas from the [Ethereum's Modified Merkle Patricia Trie (MPT)](https://ethereum.org/en/developers/docs/data-structures-and-encoding/patricia-merkle-trie/) and also introduce a novel approach for organizing nodes as tiny [Sparse Merkle Trees](https://eprint.iacr.org/2016/683.pdf) that result in much smaller proof sizes, and gives the name to the structure: Merkle Patricia Forestry. This optimization and overall approach are covered in more detail [in the wiki](https://github.com/aiken-lang/merkle-patricia-forestry/wiki/Technical-analysis#forestry).

While this optimization sacrifices some memory and CPU execution units for smaller proof sizes, the library ultimately achieves a good trade-off. The table below summarizes the proof size, memory units, and CPU units for various sizes of tries. Note that the numbers in the table correspond to _one proof verification_ (e.g., membership). Insertion and deletion in the trie both require _two proof verifications_, so double the numbers!

trie size | avg proof size (bytes) | avg proof mem units | avg proof cpu units |
---: | -------------: | ------------: | ------------: |
10² | 250 | 70K <sup>(0.70%)</sup> | 18M <sup>(0.12%)</sup> |
10³ | 350 | 100K <sup>(1.00%)</sup> | 26M <sup>(0.19%)</sup> |
10⁴ | 460 | 130K <sup>(1.30%)</sup> | 35M <sup>(0.25%)</sup> |
10⁵ | 560 | 160K <sup>(1.60%)</sup> | 44M <sup>(0.31%)</sup> |
10⁶ | 670 | 190K <sup>(1.90%)</sup> | 53M <sup>(0.38%)</sup> |
10⁷ | 780 | 220K <sup>(2.20%)</sup> | 62M <sup>(0.44%)</sup> |
10⁸ | 880 | 250K <sup>(2.50%)</sup> | 71M <sup>(0.51%)</sup> |
10⁹ | 990 | 280K <sup>(2.80%)</sup> | 79M <sup>(0.56%)</sup> |
## Documentation

The documentation is generated from `aiken docs` and [available here](https://aiken-lang.github.io/merkle-patricia-forestry/aiken/merkle_patricia_forestry.html).

### Examples

A non-trivial example of a [fruit map](https://github.com/aiken-lang/merkle-patricia-forestry/blob/main/on-chain/lib/aiken/merkle-patricia-forestry.tests.ak#L90) is available in the source. It illustrate how to use the various `from_root`, `has`, `insert` and `delete` primitives.

```aiken
test insert_bitcoin_block_845602() {
let trie =
mpf.from_root(
#"225a4599b804ba53745538c83bfa699ecf8077201b61484c91171f5910a4a8f9",
)
let block_hash =
#"0000000000000000000261a131bf48cc5a19658ade8cfede99dc1c3933300d60"
let block_body =
#"26f711634eb26999169bb927f629870938bb4b6b4d1a078b44a6b4ec54f9e8df"
mpf.insert(trie, block_hash, block_body, proof_bitcoin_845602()) == mpf.from_root(
#"507c03bc4a25fd1cac2b03592befa4225c5f3488022affa0ab059ca350de2353",
)
}
fn proof_bitcoin_845602() -> Proof {
[
Branch {
skip: 0,
neighbors: #"bc13df27a19f8caf0bf922c900424025282a892ba8577095fd35256c9d553ca120b8645121ebc9057f7b28fa4c0032b1f49e616dfb8dbd88e4bffd7c0844d29b011b1af0993ac88158342583053094590c66847acd7890c86f6de0fde0f7ae2479eafca17f9659f252fa13ee353c879373a65ca371093525cf359fae1704cf4a",
},
Branch {
skip: 0,
neighbors: #"255753863960985679b4e752d4b133322ff567d210ffbb10ee56e51177db057460b547fe42c6f44dfef8b3ecee35dfd4aa105d28b94778a3f1bb8211cf2679d7434b40848aebdd6565b59efdc781ffb5ca8a9f2b29f95a47d0bf01a09c38fa39359515ddb9d2d37a26bccb022968ef4c8e29a95c7c82edcbe561332ff79a51af",
},
Branch {
skip: 0,
neighbors: #"9d95e34e6f74b59d4ea69943d2759c01fe9f986ff0c03c9e25ab561b23a413b77792fa78d9fbcb98922a4eed2df0ed70a2852ae8dbac8cff54b9024f229e66629136cfa60a569c464503a8b7779cb4a632ae052521750212848d1cc0ebed406e1ba4876c4fd168988c8fe9e226ed283f4d5f17134e811c3b5322bc9c494a598b",
},
Branch {
skip: 0,
neighbors: #"b93c3b90e647f90beb9608aecf714e3fbafdb7f852cfebdbd8ff435df84a4116d10ccdbe4ea303efbf0f42f45d8dc4698c3890595be97e4b0f39001bde3f2ad95b8f6f450b1e85d00dacbd732b0c5bc3e8c92fc13d43028777decb669060558821db21a9b01ba5ddf6932708cd96d45d41a1a4211412a46fe41870968389ec96",
},
Branch {
skip: 0,
neighbors: #"f89f9d06b48ecc0e1ea2e6a43a9047e1ff02ecf9f79b357091ffc0a7104bbb260908746f8e61ecc60dfe26b8d03bcc2f1318a2a95fa895e4d1aadbb917f9f2936b900c75ffe49081c265df9c7c329b9036a0efb46d5bac595a1dcb7c200e7d590000000000000000000000000000000000000000000000000000000000000000",
},
]
}
```

> [!NOTE]
>
> On current mainnet, 140K mem units and 100M cpu units corresponds respectively to 1% of the maximum transaction mem and cpu budgets.
> [!WARNING]
> The proofs themselves have been generated from a trie built with the [off-chain package](../off-chain). While theoretically possible, the Aiken library doesn't contain any primitives for constructing tries _on-chain_, even for debugging.
File renamed without changes.
2 changes: 1 addition & 1 deletion on-chain/aiken.toml → aiken.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name = "aiken-lang/merkle-patricia-forestry"
version = "main/on-chain"
version = "2.0.0"
license = "MPL-2.0"
description = "Aiken contracts for project 'aiken-lang/merkle-patricia-forestry'"

Expand Down
File renamed without changes.
File renamed without changes.
1 change: 0 additions & 1 deletion off-chain/.nvmrc

This file was deleted.

Loading

0 comments on commit 4506510

Please sign in to comment.