Mutant: Decentralized P2P Mutable Key-Value Storage for Autonomi
Mutant is a decentralized P2P mutable key-value storage system built on the Autonomi network, featuring chunking, encryption, resumable uploads, pad recycling, daemon architecture, and background task management with a powerful async Rust API + CLI.
Note: No LLMs were harmed in the making of this project.
Table of Contents
- Core Concepts
- Getting Started
- Installation
- Quick start demo
- Command-Line Interface (CLI)
- Library Usage
- Development and Testing
- Migration
- Architecture Overview
- Configuration
- License
- Contributing
Core Concepts
- Decentralized: Data is stored on the Autonomi decentralized storage network, not a centralized server. This means that no one can censor you, and you are in control of your own data, and it is accessible for anyone from anywhere. (If you wish so)
- Mutable: Data can be updated and deleted, and the changes are persisted on the network.
- Key-Value Storage: Offers a clean, asynchronous key-value interface (
get
,put
,rm
). - Public/Private Uploads: Store data publicly to share with others (no encryption) or store privately (encrypted with your private key).
- Resumable Uploads: Automatic resume of interrupted uploads; pick up right where you left off.
- Configurable Upload Size: Split the data into smaller or bigger chunks to optimize the upload speed and storage costs (default is 2MiB).
- Fetch History: Keep track of the public data you've fetched to re-fetch it later.
- Efficient Space Reuse: Frees and reuses storage pads, minimizing storage costs.
- Local Cache Index: Fast local lookups and seamless remote synchronization.
- Sync: Synchronize your local index with the remote storage.
- Recycling Bad Pads: Automatically recycle bad pads to stay performant.
- Health Check: Perform a health check on keys and reupload pads that give an error.
- Background Processing: Run operations in the background with task management.
- Daemon Architecture: Persistent daemon process handles network connections and operations.
- Task Management: Monitor, query, and control background tasks.
- Async-first Design: Built on
tokio
for high-performance non-blocking operations. - Dual Interface: Use as a Rust library (
mutant-lib
) or via themutant
CLI.
Getting Started
Prerequisites
- Rust Toolchain (latest stable recommended)
ant
CLI configured with a wallet (see below)
Setup Rust Toolchain
This will install rustup
|
This will install the latest stable version of the Rust toolchain and cargo
Setup ant
Wallet
If you just want to fetch public data, you can skip this section.
Before using mutant
to actually store data, you need to have an ant
wallet configured for the target network (Mainnet by default, or Devnet if using the --local
flag). If you don't have ant
installed, you can get it using antup:
|
This will install the ant
CLI and configure it for the Mainnet.
Once ant
is installed, if you haven't already, you can import your existing Ethereum/ANT wallet's private key using the ant
CLI:
Replace YOUR_PRIVATE_KEY_HERE
with your actual private key. mutant
will automatically detect and use this wallet.
Alternatively, you can create a new empty wallet using ant wallet create
and fund it with the necessary ANT or ETH later.
MutAnt will look for your ant wallets and ask you which one you want to use if you have multiple on the first run, then save your choice in ~/.config/mutant/config.json
.
Installation
Quick start demo
You can fetch the daily meme of the day with the following command:
Command-Line Interface (CLI)
MutAnt includes the mutant
command for convenient command-line access. When run without arguments, it defaults to listing your stored keys.
CLI Usage Examples:
Usage: mutant [OPTIONS] [COMMAND]
Commands:
put Store a value associated with a key
get Retrieve a value associated with a key
rm Remove a key-value pair
ls List stored keys
stats Show storage statistics
tasks Manage background tasks
daemon Manage the daemon
sync Synchronize local index cache with remote storage
purge Perform a get check on scratchpads that should have been created but failed at some point. Removes the pads that are not found.
import Import scratchpad private key from a file
export Export all scratchpad private key to a file
health-check Perform a health check on scratchpads that should have been created but cannot be retrieved. Recycles the pads that are not found.
help Print this message or the help of the given subcommand(s)
Options:
-q, --quiet Suppress progress bar output
-h, --help Print help
-V, --version Print version
Basic Usage:
Store/fetch private data
# Store a the file `data.txt` under the name `mykey`
# Get a value and save to a file
# Run operations in the background
# Remove a value
Store/fetch public data
# Store data publicly (no encryption) under a name
# Get your own public data by name
# Get public data by address
# You can update public data by using the same key
Daemon and task management
# Start the daemon (happens automatically when needed)
# Check daemon status
# List background tasks
# Get details of a specific task
# Stop a running task
Stats and management
# List stored keys
)
# List stored keys with fetch history
# Sync local index with remote storage
# View storage statistics
)
# Perform health check on a specific key with recycling enabled
Library Usage
Add mutant-lib
and its dependencies to your Cargo.toml
:
[]
= "0.6.2" # Or the version you need
= { = "1", = ["full"] }
Library Example:
This example demonstrates initializing the necessary components and performing basic private store/fetch operations. It assumes you have an ant
wallet setup.
use ;
async
Fetching Public Data (Keyless Initialization)
If your application only needs to retrieve publicly stored data (using store_public
) and doesn't need to manage private data, you can initialize a lightweight MutAnt
instance without a private key using MutAnt::init_public()
:
use ;
use ScratchpadAddress;
use Result;
async
This keyless instance is optimized for fetching public data and cannot perform operations requiring a private key .
### Using the Daemon and Client
For most applications, it's recommended to use the daemon architecture:
```rust
use MutantClient;
use Result;
async
Donate
If you find this project useful, you can donate to support its development. <3
ETH/ANT 0x3376C33FdC0c885cef483690ffDd1e0Ff0Eb026c