5 unstable releases
0.3.0 | Aug 1, 2021 |
---|---|
0.2.1 | May 30, 2021 |
0.2.0 | May 9, 2021 |
0.1.1 | May 9, 2021 |
0.1.0 | Apr 25, 2021 |
#4 in #subspace
72KB
1.5K
SLoC
spartan-farmer
A proof-of-concept farmer for the Subspace Network Blockchain
Overview
Notes: The code is un-audited and not production ready, use it at your own risk.
This repo is an implementation of a Farmer, designed to work with a seperate Client that implements Spartan Proof-of-Capacity (PoC) consensus. PoC is a generic term for consensus based on disk space, including proofs of space, storage, space-time, and replication. A farmer is similar to a miner in a proof-of-work blockchain, but instead of wasting CPU cycles, it wastes disk space. Much of this code is based on our earlier implementation, subspace-core-rust.
This work is supported by a Web 3 Foundation grant to develop PoC consensus for the Substrate framework. It is specifically designed to work with spartan-client, a substrate client based on the substrate-node-template.
Spartan is a stepping stone towards the larger goal of deploying Subspace as a parachain on the Polkadot Network. Subspace is a proof-of-storage blockchain that resolves the farmer's dilemma, to learn more read our white paper.
Some Notes on Plotting
Time to Plot
Plotting time is roughly linear with respect to number of cores and clock speed of the host system. On average, it takes ~ 1 minute to create a 1GB plot or 18 hours to to create a 1TB plot, though these numbers will depend on the system used. This is largely independent of the storage media used (i.e. HDD, SATA SSD, NVME SSD) as it is largely a CPU-bound task.
Disk Wear and Tear
Some PoC protocols require several passes over the disk in order to plot. For example, a 100GB plot might actually consume several TB of writes and reduce the expected lifetime of the disk. This is not the case with Spartan. The plot is created in a single pass on startup.
Storage Overhead
In addition the plot, a small Binary Search Tree (BST) is also stored on disk using RocksDB. This adds roughly 1% storage overhead. So creating a 1GB plot will actually consume about 1.01 GB of storage.
Run with Docker
The simplest way to use spartan-farmer is to use container image:
docker volume create spartan-farmer
docker run --rm -it --mount source=spartan-farmer,target=/var/spartan subspacelabs/spartan-farmer --help
spartan-farmer
is the volume where plot and identity will be stored, it only needs to be created once.
Install and Run Manually
Instead of Docker you can also install spartan-farmer natively by compiling it using cargo.
Notes: This will currently only work on Mac and Linux, not Windows.
If you have not previously installed the gmp_mpfr_sys
crate, follow these instructions.
RocksDB on Linux needs LLVM/Clang:
sudo apt-get install llvm clang
Then install the framer using Cargo:
cargo +nightly install spartan-farmer
NOTE: Above command requires nightly compiler for now, make sure to install it if you don't have one yet:
rustup toolchain install nightly
Usage
Commands here assume you installed native binary, but you can also easily adapt them to using with Docker.
Use --help
to find out all available commands and their options:
spartan-farmer --help
Create a New Plot
spartan-farmer plot <optional parameters> <piece-count> <seed>
This will create a 1 GB plot:
spartan-farmer plot 256000 test
For all supported options check help:
spartan-farmer plot --help
By default, plots are written to the OS-specific users local data directory.
Linux
$XDG_DATA_HOME or /home/alice/.local/share
$HOME/.local/share
macOS
$HOME/Library/Application Support /Users/Alice/Library/Application Support
Windows
{FOLDERID_LocalAppData} C:\Users\Alice\AppData\Local
Start the farmer
RUST_LOG=debug spartan-farmer farm
This will connect to local node and will try to solve on every slot notification.
NOTE: You need to have a spartan-client node running before starting farmer, otherwise it will not be able to start
Design
The farmer has two modes: plotting and farming.
Plotting
- A genesis piece is created from a short seed.
- A new Schnorr key pair is generated, and the farmer ID is derived from the public key.
- New encodings are created by applying the time-asymmetric SLOTH permutation as
encode(genesis_piece, farmer_id, plot_index)
- Each encoding is written directly to disk.
- A commitment, or tag, to each encoding is created as
hmac(encoding, salt)
and stored within a binary search tree (BST).
This process currently takes ~ 36 hours per TiB on a quad-core machine, but for 1 GiB plotting should take between a few seconds and a few minutes.
Solving
Once plotting is complete the farmer may join the network and participate in consensus.
- Connect to a client and subscribe to
slot_notifications
via JSON-RPC. - Given a global challenge as
hash(epoch_randomness || slot_index)
andSOLUTION_RANGE
. - Derive local challenge as
hash(global_challenge || farmer_id)
. - Query the BST for the nearest tag to the local challenge.
- If it within
SOLUTION_RANGE
return aSOLUTION
else returnNone
Dependencies
~68MB
~1.5M SLoC