Giter VIP home page Giter VIP logo

snarkos's Introduction

snarkOS

Table of Contents

1. Overview

snarkOS is a decentralized operating system for zero-knowledge applications. This code forms the backbone of Aleo network, which verifies transactions and stores the encrypted state applications in a publicly-verifiable manner.

2. Build Guide

2.1 Requirements

The following are minimum requirements to run an Aleo node:

  • OS: 64-bit architectures only, latest up-to-date for security
    • Clients: Ubuntu 22.04 (LTS), macOS Ventura or later, Windows 11 or later
    • Provers: Ubuntu 22.04 (LTS), macOS Ventura or later
    • Validators: Ubuntu 22.04 (LTS)
  • CPU: 64-bit architectures only
    • Clients: 16-cores
    • Provers: 32-cores (64-cores preferred)
    • Validators: 32-cores (64-cores preferred)
  • RAM: DDR4 or better
    • Clients: 16GB of memory
    • Provers: 32GB of memory (64GB or larger preferred)
    • Validators: 64GB of memory (128GB or larger preferred)
  • Storage: PCIe Gen 3 x4, PCIe Gen 4 x2 NVME SSD, or better
    • Clients: 64GB of disk space
    • Provers: 128GB of disk space
    • Validators: 2TB of disk space (4TB or larger preferred)
  • Network: Symmetric, commercial, always-on
    • Clients: 100Mbps of upload and download bandwidth
    • Provers: 250Mbps of upload and download bandwidth
    • Validators: 500Mbps of upload and download bandwidth
  • GPU:
    • Clients: Not required at this time
    • Provers: CUDA-enabled GPU (optional)
    • Validators: Not required at this time

Please note that in order to run an Aleo Prover that is competitive, the machine will need more than these requirements.

2.2 Installation

Before beginning, please ensure your machine has Rust v1.66+ installed. Instructions to install Rust can be found here.

Start by cloning this GitHub repository:

git clone https://github.com/AleoHQ/snarkOS.git --depth 1

Next, move into the snarkOS directory:

cd snarkOS

[For Ubuntu users] A helper script to install dependencies is available. From the snarkOS directory, run:

./build_ubuntu.sh

Lastly, install snarkOS:

cargo install --locked --path .

Please ensure ports 4130/tcp and 3030/tcp are open on your router and OS firewall.

3. Run an Aleo Node

3.1 Run an Aleo Client

Start by following the instructions in the Build Guide.

Next, to start a client node, from the snarkOS directory, run:

./run-client.sh

3.2 Run an Aleo Prover

Start by following the instructions in the Build Guide.

Next, generate an Aleo account address:

snarkos account new

This will output a new Aleo account in the terminal.

Please remember to save the account private key and view key. The following is an example output:

 Attention - Remember to store this account private key and view key.

  Private Key  APrivateKey1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  <-- Save Me And Use In The Next Step
     View Key  AViewKey1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  <-- Save Me
      Address  aleo1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  <-- Save Me

Next, to start a proving node, from the snarkOS directory, run:

./run-prover.sh

When prompted, enter your Aleo private key:

Enter the Aleo Prover account private key:
APrivateKey1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

4. FAQs

1. My node is unable to compile.

  • Ensure your machine has Rust v1.66+ installed. Instructions to install Rust can be found here.
  • If large errors appear during compilation, try running cargo clean.
  • Ensure snarkOS is started using ./run-client.sh or ./run-prover.sh.

2. My node is unable to connect to peers on the network.

  • Ensure ports 4130/tcp and 3030/tcp are open on your router and OS firewall.
  • Ensure snarkOS is started using ./run-client.sh or ./run-prover.sh.

3. I can't generate a new address

  • Before running the command above (snarkos account new) try source ~/.bashrc
  • Also double-check the spelling of snarkos. Note the directory is /snarkOS, and the command is snarkos

4. How do I use the CLI to sign and verify a message?

  1. Generate an account with snarkos account new if you haven't already
  2. Sign a message with your private key using snarkos account sign --raw -m "Message" --private-key-file=<PRIVATE_KEY_FILE>
  3. Verify your signature with snarkos account verify --raw -m "Message" -s sign1SignatureHere -a aleo1YourAccountAddress

Note, using the --raw flag with the command will sign plaintext messages as bytes rather than Aleo values such as 1u8 or 100field.

5. Command Line Interface

To run a node with custom settings, refer to the options and flags available in the snarkOS CLI.

The full list of CLI flags and options can be viewed with snarkos --help:

snarkOS 
The Aleo Team <[email protected]>

USAGE:
    snarkos [OPTIONS] <SUBCOMMAND>

OPTIONS:
    -h, --help                     Print help information
    -v, --verbosity <VERBOSITY>    Specify the verbosity [options: 0, 1, 2, 3] [default: 2]

SUBCOMMANDS:
    account    Commands to manage Aleo accounts
    clean      Cleans the snarkOS node storage
    help       Print this message or the help of the given subcommand(s)
    start      Starts the snarkOS node
    update     Update snarkOS

The following are the options for the snarkos start command:

USAGE:
    snarkos start [OPTIONS]

OPTIONS:
        --network <NETWORK_ID>                  Specify the network ID of this node [default: 3]
        
        --validator                             Specify this node as a validator
        --prover                                Specify this node as a prover
        --client                                Specify this node as a client
        
        --private-key <PRIVATE_KEY>             Specify the node's account private key
        --private-key-file <PRIVATE_KEY_FILE>   Specify the path to a file containing the node's account private key
        
        --node <IP:PORT>                        Specify the IP address and port for the node server [default: 0.0.0.0:4130]
        --connect <IP:PORT>                     Specify the IP address and port of a peer to connect to
 
        --rest <REST>                           Specify the IP address and port for the REST server [default: 0.0.0.0:3030]
        --norest                                If the flag is set, the node will not initialize the REST server
        
        --nodisplay                             If the flag is set, the node will not render the display
        --verbosity <VERBOSITY_LEVEL>           Specify the verbosity of the node [options: 0, 1, 2, 3] [default: 2]
        --logfile <PATH>                        Specify the path to the file where logs will be stored [default: /tmp/snarkos.log]
        
        --dev <NODE_ID>                         Enables development mode, specify a unique ID for this node

6. Development Guide

6.1 Quick Start

In the first terminal, start the first validator by running:

cargo run --release -- start --nodisplay --dev 0 --validator

In the second terminal, start the second validator by running:

cargo run --release -- start --nodisplay --dev 1 --validator

In the third terminal, start the third validator by running:

cargo run --release -- start --nodisplay --dev 2 --validator

In the fourth terminal, start the fourth validator by running:

cargo run --release -- start --nodisplay --dev 3 --validator

From here, this procedure can be used to further start-up provers and clients.

6.2 Operations

It is important to initialize the nodes starting from 0 and incrementing by 1 for each new node.

The following is a list of options to initialize a node (replace <NODE_ID> with a number starting from 0):

cargo run --release -- start --nodisplay --dev <NODE_ID> --validator
cargo run --release -- start --nodisplay --dev <NODE_ID> --prover
cargo run --release -- start --nodisplay --dev <NODE_ID> --client
cargo run --release -- start --nodisplay --dev <NODE_ID>

When no node type is specified, the node will default to --client.

6.3 Local Devnet

6.3.1 Install tmux

To run a local devnet with the script, start by installing tmux.

macOS

To install tmux on macOS, you can use the Homebrew package manager. If you haven't installed Homebrew yet, you can find instructions at their website.

# Once Homebrew is installed, run:
brew install tmux
Ubuntu

On Ubuntu and other Debian-based systems, you can use the apt package manager:

sudo apt update
sudo apt install tmux
Windows

There are a couple of ways to use tmux on Windows:

Using Windows Subsystem for Linux (WSL)

  1. First, install Windows Subsystem for Linux.
  2. Once WSL is set up and you have a Linux distribution installed (e.g., Ubuntu), open your WSL terminal and install tmux as you would on a native Linux system:
sudo apt update
sudo apt install tmux

6.3.2 Start a Local Devnet

To start a local devnet, run:

./devnet.sh

Follow the instructions in the terminal to start the devnet.

6.3.3 View a Local Devnet

Switch Nodes (forward)

To toggle to the next node in a local devnet, run:

Ctrl+b n

Switch Nodes (backwards)

To toggle to the previous node in a local devnet, run:

Ctrl+b p

Select a Node (choose-tree)

To select a node in a local devnet, run:

Ctrl+b w

Select a Node (manually)

To select a node manually in a local devnet, run:

Ctrl+b :select-window -t {NODE_ID}

6.3.4 Stop a Local Devnet

To stop a local devnet, run:

Ctrl+b :kill-session

Then, press Enter.

Clean Up

To clean up the node storage, run:

cargo run --release -- clean --dev <NODE_ID>

7. Contributors

Thank you for helping make snarkOS better!
๐Ÿง What do the emojis mean?

Howard Wu
Howard Wu

๐Ÿ’ป ๐Ÿšง ๐Ÿค” ๐Ÿ‘€
Raymond Chu
Raymond Chu

๐Ÿ’ป ๐Ÿšง ๐Ÿค” ๐Ÿ‘€
ljedrz
ljedrz

๐Ÿ’ป ๐Ÿšง ๐Ÿค” ๐Ÿ‘€
Niklas Long
Niklas Long

๐Ÿ’ป ๐Ÿšง ๐Ÿค” ๐Ÿ‘€
Collin Chin
Collin Chin

๐Ÿ’ป ๐Ÿ“– ๐Ÿ‘€
Mike Turner
Mike Turner

๐Ÿ’ป ๐Ÿ“– ๐Ÿ‘€
Georgios Konstantopoulos
Georgios Konstantopoulos

๐Ÿ’ป
Kobi Gurkan
Kobi Gurkan

๐Ÿ’ป
Vesa-Ville
Vesa-Ville

๐Ÿ’ป
jules
jules

๐Ÿ’ป
Daniil
Daniil

๐Ÿ’ป
akattis
akattis

๐Ÿ’ป
William Cannon
William Cannon

๐Ÿ’ป
wcannon-aleo
wcannon-aleo

๐Ÿ’ป
Sam De Roeck
Sam De Roeck

๐Ÿ’ป
soft2dev
soft2dev

๐Ÿ’ป
Ali Mousa
Ali Mousa

๐Ÿ’ป
pyk
pyk

๐Ÿ’ป
Belsy
Belsy

๐Ÿ’ป
apruden2008
apruden2008

๐Ÿ’ป
Fabiano Prestes
Fabiano Prestes

๐Ÿ’ป
Haruka
Haruka

๐Ÿ’ป
e4m7he6g
e4m7he6g

๐Ÿ’ป
Gregรณrio Granado Magalhรฃes
Gregรณrio Granado Magalhรฃes

๐Ÿ’ป
Evgeny Garanin
Evgeny Garanin

๐Ÿ’ป
Macro Hoober
Macro Hoober

๐Ÿ’ป
code-pangolin
code-pangolin

๐Ÿ’ป
kaola526
kaola526

๐Ÿ’ป
clarenous
clarenous

๐Ÿ’ป
Kostyan
Kostyan

๐Ÿ’ป
Austin Abell
Austin Abell

๐Ÿ’ป
Youssef El Housni
Youssef El Housni

๐Ÿ’ป
ghostant-1017
ghostant-1017

๐Ÿ’ป
Miguel Gargallo
Miguel Gargallo

๐Ÿ’ป
Chines Wang
Chines Wang

๐Ÿ’ป
Ayush Goswami
Ayush Goswami

๐Ÿ’ป
Tim - o2Stake
Tim - o2Stake

๐Ÿ’ป
liu-sen
liu-sen

๐Ÿ’ป
Palamar
Palamar

๐Ÿ’ป
swift-mx
swift-mx

๐Ÿ’ป
Caesar Wang
Caesar Wang

๐Ÿ’ป
Paul IP
Paul IP

๐Ÿ’ป
Philip Glazman
Philip Glazman

๐Ÿ’ป
Ruslan Nigmatulin
Ruslan Nigmatulin

๐Ÿ’ป
Franรงois Garillot
Franรงois Garillot

๐Ÿ’ป
aolcr
aolcr

๐Ÿ’ป
Maciej Zwoliล„ski
Maciej Zwoliล„ski

๐Ÿ’ป
Nacho Avecilla
Nacho Avecilla

๐Ÿ’ป
Max Bruce
Max Bruce

๐Ÿ’ป
whalelephant
Belsy

๐Ÿ’ป
tranhoaison
Santala

๐Ÿ’ป
web3deadline
deadline

๐Ÿ’ป
CedricYanYuhui
CedricYanYuhui

๐Ÿ’ป
craigjson
Craig Johnson

๐Ÿ’ป
vbar
Vaclav Barta

๐Ÿ’ป
Dependabot
Dependabot

๐Ÿ’ป
Add your contributions

This project follows the all-contributors specification. Contributions of any kind are welcome!

8. License

We welcome all contributions to snarkOS. Please refer to the license for the terms of contributions.

License: GPL v3

snarkos's People

Contributors

akattis avatar amousa11 avatar apruden2008 avatar collinc97 avatar d0cd avatar daniilr avatar dependabot-preview[bot] avatar dependabot[bot] avatar gakonst avatar ghostant-1017 avatar howardwu avatar iamalwaysuncomfortable avatar joske avatar jules avatar kobigurk avatar ljedrz avatar mdelle1 avatar meshiest avatar miazn avatar niklaslong avatar protryon avatar raychu86 avatar sadroeck avatar splittydev avatar tudorpintea999 avatar vbar avatar vicsn avatar vvp avatar wcannon avatar wcannon-aleo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

snarkos's Issues

Dynamic test data generation

The test data in consensus/src/test_data/mod.rs is hard coded for particular parameters and DPC logic. If any of the DPC circuits change or parameters change, this data will need to be updated.

A solution to this is to add a script that regenerates this test data whenever breaking changes are made to other modules of snarkOS.

Remove `test_data` directories from all modules.

Add a new module that handles all logic currently distributed in the test_data directories in consensus, dpc, and network. This module will be imported as a dev dependency and used for tests only.

This will reduce unnecessary compilation.

Introduce `network_id` to DPC transactions

TLDR: Account public keys should reflect if the given private key is a mainnet or testnet account.

To incorporate this, we update our generation of account public keys from a commitment of three inputs, to a commitment comprised of four inputs now (in addition to the randomness input).

Our current account public key is produced as follows:

let commit_input = to_bytes![private_key.pk_sig, private_key.sk_prf, private_key.metadata]?;
let commitment = C::AccountCommitment::commit(parameters, &commit_input, &private_key.r_pk)?;

Our new account public key will be produced as follows:

let commit_input = to_bytes![private_key.pk_sig, private_key.sk_prf, private_key.metadata, private_key.is_testnet]?;
let commitment = C::AccountCommitment::commit(parameters, &commit_input, &private_key.r_pk)?;

Implement macro to generate Parameters

We probably should write a macro which impls Parameters, which would be invoked like so:

impl_params!(AccountCommitmentParameters, "./account_commitment.checksum", 417868, "./account_commitment.params");

this would reduce the LoC of the parameters module and make it easier to maintain / review when changes are needed.

In that case I can see us removing all the .rs files in the module and just calling the impl macro in the lib.rs file. Then, we could also move all the .params and .sum files to a subdirectory called params (or something)

Originally posted by @gakonst in #184

Add transaction ID

Include a transaction hash field in the Transaction struct so it is standardized

Change snarkOS command line conventions

  • When using flags, change default convention to pass flags in from cargo run test to cargo run --
  • Change miner flag from --miner to --is-miner
  • Change all underscore convention to dash convention (e.g. --is_bootnode to --is-bootnode)

Merkle tree leaf hashing is done on a larger buffer than necessary

The buffer allocated to hash the leaf is larger than the leaf size in order to be able to use the hash_inner_node function:

let mut buffer = [0u8; 128];

While this works for us now in POSW (since Pedersen is homomorphic and the 0s do not change the hash) and using Blake2s (since it works anyway on 512-bit chunks), we might want to change it so there's no confusion in the future.

Must not get difficulty from the header

Currently, when checking the PoW against the difficulty target, the verification trusts that the difficulty target in the header is correctly set. A malicious peer could feed us with a block that has the wrong target. Instead, the difficulty should be obtained via self.get_block_difficulty

Add additional RPC support

A few features/fixes need to be added to the RPC:

  1. Direct fetching of transaction information
  2. Get block time information when fetching block info
  3. Fix get_block_template
  4. Clean up and add additional RPC tests
  5. Logic for reasoning about non-canon blocks

Remove `parameters` from `snarkos-dpc`

These parameters should not live in the dpc submodule. File path references to these parameters should be removed and these parameters should only be accessible at the requisite point of use.

Restructure ledger instantiation

Currently the ledger is instantiated by ledger_storage using a genesis record serial number, genesis record commitment, and a genesis memo. A more intuitive design is to instantiate a genesis block with prepared genesis transactions, and have ledger_storage parse this genesis block and add it to the system's state.

To implement this, we will need to do the following:

  • Generate predicate_vk_hash when transactions are generated in consensus
  • Add a genesis submodule with prepared genesis transactions, and logic to construct the genesis block
  • Update LedgerStorage to initialize the system using the genesis block
  • Remove genesis_serial_number, genesis_commitment, genesis_memo, genesis_predicate_vk_bytes, and genesis_account

[README] Instructions to start a node

Assuming compilation works, we need basic instructions for how to start a node and operate it. Given anticipated changes, a few steps will be sufficient for the time being.

Investigate a cleaner design for masked Pedersen and Merkle tree

The design we've settled on for now is introducing a new MaskedCRHGadget with an evaluation function that receive a mask and a compute_root gadget that computes a root given a mask and a MaskedCRHGadget implementation.

A cleaner design would be to define a new masked Pedersen CRH which receives the mask at initialization time and exposes the normal evaluation functions, and so the Merkle tree would be oblivious to the fact it's using a masked CRH.

The current design of the Pedersen CRH gadget make it hard, since it expects to share the parameters between the native and gadget implementation. This in turn requires us to introduce a native implementation of the masked Pedersen CRH, which is an unnecessary complexity.

Split `DPC` into subtraits and individual structs

This step was originally intended to be performed after migration to snarkVM.

As parameters have become a blocker, we're moving up this split to facilitate the migration of parameters and testing parameters out of snarkos-dpc and into genesis and testing modules.

This split should help to ensure developers have inconvenient access to the Setup operation, and enforce system safety for Aleo runtimes.

Add Docker container

Create a docker image to standardize testing and runtime environment.

Potentially useful for debugging a flaky network test specific to Travis CI (see #80)

Merge uint gadgets to master

Currently leo relies on uint gadgets that are part of branch feature/integers. The changes on this branch need to merged for leo to work with the master branch of snarkOS

Merkle tree does extra hashing that increases the cost in POSW

The native Merkle tree implementation is doing extra hashing which is not crucial:

  • The root hash is being hashed: againhttps://github.com/AleoHQ/snarkOS/blob/51b71c1cbd9eec0ccd95016a1b247ce0cd1f2375/algorithms/src/merkle_tree/merkle_tree.rs#L72
  • The leaves are hashed:
    tree[last_level_index + i] = parameters.hash_leaf(leaf, &mut buffer)?;

Both of them are not necessary for correctness/security (although hashing the leaves is standard practice).

If we remove these then the proof can be focused on hashing the transaction IDs, resulting in a higher possible capacity.

Fix node public IP discovery and bootnode connection

Currently nodes start up with a socket address of 0.0.0.0 or 127.0.0.1 with no knowledge of their own public IP. This creates an issue with handshake connections because sending 0.0.0.0 or 127.0.0.1 to the peer gives them no context.

A current solution is to manually set the public ip of the node in config.rs or the --ip cli option so that the node has knowledge of it's own public ip address.

There needs to be a more seamless experience for node operators to not have to manually input their public ip when starting their node.

Block forking and updated sync logic

Currently the consensus logic for handling blocks (DPC) is naive. There needs to be more sophisticated logic for block selection and forking when operating with many disjoint nodes.

Additional feature requirements:

  • Block caching
  • Chain forking
  • New block propagation and sync logic
  • Regular clearing of invalidated orphan blocks (based on established thresholds)

Node is_bootnode configuration parsing fails

Steps to reproduce:

  1. Run cargo run test --is_bootnode
  2. See error - index out of bounds: the len is 0 but the index is 0

Fix:

Add check during bootnode parsing to ensure vector is non-empty.

Storage of Delegated DPC Components

The delegated DPC Implementation is currently a standalone application without permanent state/storage. New storage standards need to be put in place and the current database implementation needs to be refactored to fit the DPC protocol.

Requirements:

  • Database Redesign
  • Public Parameter Storage and Retrieval
  • Block/Transaction Storage
  • Integrate IdealLedger components

Minimal parameter loading

Currently SnarkOS loads both the proving and verifying by default.

This is quite inefficient. Light clients should be able to just select just the verifying parameters if they are not generating transactions or mining.

Refactor ledger's genesis attributes

Currently LedgerStorage is instantiated from attributes in storage/src/genesis.rs. This is poorly designed, as it uses hard coded values that must be changed when parameters are updated.

The solution is to migrate these attributes to the parameters module and be generated whenever parameters are generated. This will help prevent breaking changes to storage when other modules are updated.

Remove mining in genesis block generation script

The genesis block doesn't need to be mined because the consensus module doesn't need to verify the validity of the block.

The mining logic in genesis/examples/create_genesis_block.rs can be safely removed.

Remove `Storage` trait implementations

Use of Storage trait for algorithms is bad engineering design.

Instead, we should be implementing a load functionality as a wrapper call for parameters that use algorithms.

Flaky networking test

Master currently is broken with the following error which I presume is a flaky test:

https://travis-ci.com/github/AleoHQ/snarkOS/jobs/329788277

test server_listen::startup_handshake_stored_peers ... FAILED
failures:
---- server_listen::startup_handshake_stored_peers stdout ----
thread 'server_listen::startup_handshake_stored_peers' panicked at 'called `Result::unwrap()` on an `Err` value: ConnectError(Crate("std::io", "Os { code: 104, kind: ConnectionReset, message: \"Connection reset by peer\" }"))', network/tests/server_listen.rs:198:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
    server_listen::startup_handshake_stored_peers

Tracking: Migration of select submodules from `snarkOS` into `snarkVM`

In an effort to formalize Aleo records (for usability), reduce miner code dependencies (for security), and introduce an abstraction layer for DPC (for modularity), we are migrating select submodules from snarkOS into snarkVM.

  • algorithms
  • benchmarks
  • curves
  • dpc
  • gadgets

This migration will allow snarkVM to focus on its core functionality of facilitating predicate (application) executions, producing DPC records, and composing records into transactions. This migration will also simplify the existing dependency chain for a number of repositories currently upstream. In addition, this migration should improve snarkOS compile times significantly.

In preparation for this migration, there are a few updates snarkOS will need to make in order to ensure a smooth transition.

  • #139 - Remove Storage trait implementations
  • #140 - Remove parameters from snarkos-dpc

To complete this migration, 3 submodules in snarkOS will need a minor update, calling components from snarkVM now.

In snarkos-consensus:

  • dpc - InstantiatedDPC will be called from snarkVM
  • dpc - PublicParameters will be called from snarkVM

In snarkos-network:

  • dpc - Instantiated components of DPC will be called from snarkVM
  • dpc - InstantiatedDPC will be called from snarkVM
  • dpc - PublicParameters will be called from snarkVM

In snarkos-posw:

  • gadgets - Merkle gadget will be called from snarkVM
  • curves - BLS12-377 will be called from snarkVM

Lastly, prior to publishing snarkVM to Crates.io, to ensure Travis CI continues to run, a private dependency link will be used for continuous integration.

Update DPC outer_snark to verify inner_snark proof

After discussion with @Pratyush and Ian, we will add one proof-check circuit to the outer_snark to verify the inner_snark proof. In doing this, we can remove the inner_proof from transactions.

This change results in a 15% increase in time to produce a transaction, however it reduces transaction sizes by 20+%. This also simplifies transaction verification logic for miners and clients by removing the inner_snark proof check in software, and will result in a speedup for transaction verification.

Generalize structs to not require MerkleTreeLedger and DPCTransaction

Inside the consensus package, there's a lot of places where the MerkleTreeLedger and the Tx instantiated datatypes are used. Instead, we should be using generics which conform to the Tx: Transaction, P: MerkleParameters and LedgerStorage<Tx, P> traits, so that we're able to run tests with a TestTx data structure. This would allow us to run our tests much faster and in a more scalable way, since we would be able to create blocks with transactions that do not require proving.

Examples:

  • ConsensusParameters
  • Miner
  • snarkos-network's Server (and all associated helper methods)

A lot of the tests which are written as integration tests and use a on-disk database can then be re-written as unit tests with much more extensive coverage (and quicker to run)

Move and rename db

Have snarkOS create a ~/.snarkOS directory and have the RocksDB file be called snarkos_db and snarkos_test_db, or something equivalent.

Improve Developer Experience around Public Parameters generation

Anytime the circuits are changed, the public parameters have to be regenerated. Currently, if I change the circuit and I use an old parameters file, the code will run until it tries to verify the computation, where it'll return a Core NIZK didn't verify error. This can be very frustrating and also destroy productive developer hours (because you have to wait >1h to compile + regenerate the params).

I have the following suggestions:

  1. Since checking in the inner/outer snark parameters is not an option (because they're multiple GBs in size), I recommend we check in the hash of them, and simply throw an error if the file's hash on disk does not match the checked in hash. This allows us to error fast and in a well determined place, instead of giving an unfitting error (h/t @kobigurk)
  2. For every successful PR on CI, the generated inner/outer snark params should be automatically uploaded somewhere as artifacts (maybe an S3 bucket). Pulling from master would then be followed by a wget of the params (I prefer having to download a 3GB file which I know is going to be the correct one, to re-generating everything myself each time there's a circuit change on master.)

Also, we should investigate improving I/O performance, loading the params takes a few minutes on my box. Adding Buffered readers (and writers) might do the trick, although I suspect we might have some unnecessary math operations somewhere which hurt performance. Kobi had the following idea:

Kobi Gurkan, [21.05.20 10:38]
maybe one thing we could do to improve load/save times is to use from_repr_raw and into_repr_raw instead of the normal ones when writing/reading. This would leave out using mont_reduce. We'd also be using the [u64] directly

`Connection refused` networking test failure

Unrelated to the flaky networking test we had prior, we have come across a networking issue that is unable to be replicated on macOS, but seems reproducible on EC2 ubuntu.

Running /home/ubuntu/snarkOS/target/debug/deps/server_message_handler-fa787f9700812d1f

running 15 tests
test server_message_handler::receive_get_block ... ok
test server_message_handler::receive_block_message ... ok
test server_message_handler::receive_get_memory_pool_empty ... ok
test server_message_handler::receive_get_memory_pool_normal ... ok
test server_message_handler::receive_get_peers ... ok
test server_message_handler::receive_get_sync ... ok
test server_message_handler::receive_memory_pool ... ok
test server_message_handler::receive_peers ... ok
test server_message_handler::receive_ping ... ok
test server_message_handler::receive_pong_accepted ... FAILED
test server_message_handler::receive_pong_rejected ... FAILED
test server_message_handler::receive_pong_unknown ... ok
test server_message_handler::receive_sync ... ok
test server_message_handler::receive_sync_block ... FAILED
test server_message_handler::receive_transaction ... ok

failures:

---- server_message_handler::receive_pong_accepted stdout ----
thread 'server_message_handler::receive_pong_accepted' panicked at 'called `Result::unwrap()` on an `Err` value: Crate("std::io", "Os { code: 111, kind: ConnectionRefused, message: \"Connection refused\" }")', /home/ubuntu/snarkOS/network/src/test_data/mod.rs:73:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

---- server_message_handler::receive_pong_rejected stdout ----
thread 'server_message_handler::receive_pong_rejected' panicked at 'called `Result::unwrap()` on an `Err` value: Crate("std::io", "Os { code: 111, kind: ConnectionRefused, message: \"Connection refused\" }")', /home/ubuntu/snarkOS/network/src/test_data/mod.rs:73:5

---- server_message_handler::receive_sync_block stdout ----
thread 'server_message_handler::receive_sync_block' panicked at 'called `Result::unwrap()` on an `Err` value: Crate("std::io", "Os { code: 111, kind: ConnectionRefused, message: \"Connection refused\" }")', /home/ubuntu/snarkOS/network/src/test_data/mod.rs:73:5


failures:
    server_message_handler::receive_pong_accepted
    server_message_handler::receive_pong_rejected
    server_message_handler::receive_sync_block

test result: FAILED. 12 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out

error: test failed, to rerun pass '--test server_message_handler'

and

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

     Running /home/ubuntu/snarkOS/target/debug/deps/server_connection_handler-340a7b00af4d0aa5

running 6 tests
test server_connection_handler::gossiped_peer_disconnect ... ok
test server_connection_handler::gossiped_peer_connect ... ok
test server_connection_handler::memory_pool_interval ... FAILED
test server_connection_handler::peer_connect ... ok
test server_connection_handler::peer_disconnect ... ok
test server_connection_handler::sync_node_disconnect ... ok

failures:

---- server_connection_handler::memory_pool_interval stdout ----
thread 'server_connection_handler::memory_pool_interval' panicked at 'called `Result::unwrap()` on an `Err` value: Crate("std::io", "Os { code: 111, kind: ConnectionRefused, message: \"Connection refused\" }")', /home/ubuntu/snarkOS/network/src/test_data/mod.rs:73:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    server_connection_handler::memory_pool_interval

test result: FAILED. 5 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out

error: test failed, to rerun pass '--test server_connection_handler'

Refactor record values and value commitments

Currently, payments are handled with a payment record and a payment circuit. This means value transfer is more of an application on the network rather than intrinsic to the protocol itself. The value commitment architecture is not entirely necessary and can be modified which will benefit circuit sizes.

A solution to this is to unify the record model to always have a value field and to verify the record values and transaction value_balance directly in the InnerCircuit.

To implement this, we will need to do the following:

  • Move value out of the record payload and make it a dedicated attribute
  • Make the PaymentCircuit a generic PredicateCircuit that doesn't handle record values
    • Remove value commitment logic from PaymentCircuit
    • Update the predicate to be a generic
    • Remove value commitment logic from OuterCircuit
  • Update InnerCircuit to handle all record value and transaction value_balance checks
  • Phase out value commitments with direct value checks in the InnerCircuit

Remove value commitment attributes from the DPC transaction

Currently the value commitments are included in the payment DPC transaction along with the binding signature and value balance. The binding signature is then verified outside the DPC circuits with the value commitments and value balance.

Payment values are hidden with these commitments, but non-payment transactions will also require garbage value commitments as obfuscation.

Possible Solution

Possible solution is to remove value commitments and binding signature from the transaction and verify the binding signature in the DPC circuit (with the value balance as the public input).

This value balance is important because it allows the consensus model to accurately assign fees for the miner, who learns nothing else from the transactions.

Note: This will decrease storage size and simplify the transactions significantly, at the cost of increased circuit size and runtime

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.