Guide to Snark Work

While block producers create blockchain proofs that prove the validity of the current state of the blockchain, they do not certify the included individual transactions. Snark workers handle the task of creating these transaction proofs. Offloading these transaction proofs from the block producer to snark workers means that the transaction proof generation may be parallelized, significantly improving the network’s throughput.

Snark workers charge a fee for generating these transaction proofs and are compensated by the block producers purchasing their completed snark work. A snark worker may charge any fee for the work they produce, but a block producer will (all things being equal) purchase the work required for the lowest fee.

You can view a breakdown of each transaction snark work included on MinaExplorer under the SNARK Jobs heading on a block page.

When a block producer generates a block, they may include transactions recently seen on the network and included in the transaction pool. The block producer includes these transactions in the staged ledger via a data structure known as the scan state that becomes pending work for the snark workers to complete. For each transaction they add to the scan state, the block producer must add an equivalent amount of completed snark work from the snark pool. The snark pool contains completed transaction proofs submitted by snark workers for transactions added via prior block producers.

Running a Snark Worker

Anyone may run a snark worker with any public key, and there is no minimum amount of MINA required. However, the address used for payouts must be in the ledger, else a ledger creation fee (of 1 MINA) will be applied on the first transaction, and snark fees of less than 1 MINA will fail. When the payout address is in the ledger, you may snark with any fee.

Running a snark worker requires running a full node to get the latest work and submit completed proofs to the network. See the notes on snark coordinators to run multiple snark workers via a single daemon). To start a snark worker via the command line, run the following commands, replacing with your fee (default 0.025 MINA) and the public key of the snark worker:

Start snark worker via CLI
Copy

Alternatively, start the daemon with the addition of these two extra flags (add to your existing options):

Start snark worker automatically
Copy

Snark work is computationally expensive, and you can control the number of threads used with the -snark-worker-parallelism option. To stop a snark worker, just pass an empty address as the public key in the command mina client set-snark-worker --address

Snark stopper

If running a snark worker on a machine that also produces blocks, the snark worker may use too many resources which prevents completing the blockchain proof in time. As a result, you may not produce your block in time and forgo the coinbase rewards. To alleviate this, you can stop the snark worker when you are about to produce a block. This can be done manually as above or make use of a script such as the snark stopper script that will stop the snark worker for the duration of block production and start it up again after.

Work selection

As detailed earlier, when block producers add transactions to blocks, they must include a matching amount of snark work. These snarks are for earlier transactions added to the transaction proof queue, aka the scan state. The scan state requires work to be purchased in a specific order according to its position in the tree. So when a block producer adds a transaction, they must purchase the required piece of snark work, and they will select that work from their local snark pool. The snark pool only contains the lowest fee seen for that work. If the node sees cheaper work, it replaces the existing work in the snark pool.

When a new block is produced and gossiped, the added transactions become pending work for the snark workers to complete. Snark workers may choose how to select the work they complete, and there are two work selection algorithms in the daemon (though there is nothing to prevent you from creating your own).

The two algorithms are sequential and random. The sequential algorithm produces snark proofs in the order required by block producers. The random option, as the name suggests, selects required work randomly. Snark workers will only complete work if they can complete the work cheaper than they have in their existing snark pool.

You can set the work selection algorithm with the option --work-selection rand or --work-selection seq for sequential. Random is the default. You must restart the daemon for this to be applied.

If you run the random algorithm, it may take a while for any work you produce to be purchased as you might be completing work that is not required for some time. Generally speaking, by running the sequential algorithm, you should see faster results.

Snark coordinator

For more advanced use-cases a snark coordinator coordinates snark jobs among many snark workers. The coordinator is responsible for sending new work to the snark workers, ensuring they do not duplicate the same work.

The snark workers communicate with the snark coordinator via RPC calls. New work is requested by a snark worker using the get_work RPC call. Completed work is submitted via the submit_work daemon RPC call. Once received, the coordinator broadcasts the completed work to the network.

A snark coordinator is run by providing the -run-snark-coordinator <PUBLICKEY> option to the mina daemon command. All workers using the same coordinator will use the same public key.

A standalone snark worker may be started using the mina internal snark-worker command by providing the -daemon-address, which is the client port of the daemon running the coordinator (default 8301).

While the coordinator can be used to control multiple snark workers, as would be the case of a snark worker pool, as it communicates via the client port, it is only suitable for coordinating trusted machines. There are plans to enable snark pools, making snark work more efficient as it will help reduce duplicated work.

Choosing a Fee

Pricing snark work is part art, part science, and part luck. There is no centralized pool, and each block producer has a local snark pool from which they purchase snarks. So while snark work is gossiped between nodes, a block producer may be offline or have other issues and never see your snark work or see others first. Other than the coinbase transaction, snark fees are paid for by transaction fees.

If a node sees the same price snark work, the original will not be replaced, so while the speed of producing snark work isn't that important (it is more a factor of the price) if you are competing at, say 0 using a sequential selection, then speed may matter.

The main approaches to setting a fee are to look at historical prices of snarks in the latest blocks and/or to try to predict snark prices from the current snark pool.

For finding historical snark prices, you can get the data from prior blocks by using the daemon GraphQL API (on the node is restricted to the last 290 blocks) or via the MinaExplorer GraphQL API for all the chain history. There is a simple summary published here for the last 100 to 1000 blocks:

Example snark fees for the last 1000 blocks from MinaExplorer

Example snark fees for the last 1000 blocks from MinaExplorer

Alternatively, you can see a breakdown of the average snark fee per day on MinaExplorer here.

Charting the average snark fees on MinaExplorer

Charting the average snark fees on MinaExplorer

An alternate approach is to look at the snark pool on the node to see the current fees for each snark work. This is complicated by the fact that the fees may be replaced at any time by cheaper work and higher-priced work that is not required for some time skews the averages.

Additionally, the snark pool includes work that has already been completed or referenced in forks for the last 290 blocks, so naively calculating averages from the raw snark pool will not work. It is possible to determine which work is required by the scan state (and the order required) to infer a more accurate estimate. An example implementation for inspiration is provided here.

You can change your fee using the mina client set-snark-work-fee <FEE> command or use GraphQL to set this value dynamically. You do not need to restart the daemon.

Explore the snark pool

The snark pool contains all the completed work submitted by snark workers. The pool only maintains the lowest fee for each work bundle (group of work ids) as well as the public key and the fee required by the prover. For example, a single entry in the snark pool may contain this:

Snark Pool
Copy

The scan state structure derives the work required to be purchased by the block producer, and work must be purchased in a defined order. If there is no available snark work to purchase for a required work id, then no transactions will be included in a block (including the coinbase transaction). Additionally, a block producer will not purchase unprofitable snark work, i.e., the block producer may forgo a coinbase reward rather than spend more on snark work than they would receive. Typically, transaction fees cover the fees paid for purchased snark work.

Once work has been included in a block, it remains in the snark pool for as long as it is referenced in the last k blocks of the scan state. After that time, the snark work is removed from the snark pool.

You can view a summary of the snark pool output via the following command. Note that this will likely give different results on each node you run it on:

json
Copy

FAQ

How do I know it is working?

Blocks displayed on the explorer only include snark work that is purchased, so if you are snarking with a higher fee, they may never be purchased. To ensure that your snark worker is working correctly, you can check the logs, and you should see lines such as Submitted completed SNARK work.

You can also examine your local snark pool and grep for your public key as you should create snark work in your local snark pool before it is replaced by any cheaper work gossiped to the node.

I changed my price, but the old price is still being bought.

If you are running the snark worker with the random work selection, you may complete work that is not required for some time. That work will remain in the snark pool unless cheaper work is seen and eventually bought. This delay can be significant and depends on the number of transactions added to the scan state. So it is the snark work completed for the older price that is being bought.

My snark work was not included in the canonical chain.

Block producers are responsible for including snark work in a block. There can be multiple block producers for a slot, and/or the block producer may not produce at the correct height to make it into the canonical chain. As a result, the included work may be included in a non-canonical block, and there will be no rewards for it. It might be included in another block that makes it into the canonical chain, and non-canonical snarks are expected and does not indicate there is an issue with the snark worker.

Why do some very high fees get in when I am snarking for 0?

To include a coinbase transaction, a block producer needs to purchase a snark. They can only buy the snark required if it is in their snark pool, so as the coinbase reward is at least 720 MINA, it makes sense to pay anything up to that as it is still profitable. While it is highly unlikely someone will not produce a snark for less than that amount in certain circumstances, if the block producer has been offline for a long period, they may not have seen the cheaper work, and the expensive snark sneaks in. See this block for an example that includes a snark sold for 700 MINA, but ultimately this is just down to luck.

Why are so many snarks sold for 0?

At the time of writing, the majority of snarks are being sold for 0. This is largely a reflection of the low number of transactions and the low transaction fees. There are many users wanting to run snark workers and a lot of competition. While it is uneconomical for those running nodes, many users are already running nodes, so there are little additional costs for them to additionally run a snark worker. This will likely change as transaction throughput increases and the demand for snark work becomes greater.

Running a snark worker is computationally expensive. The recommended requirements are at least 8 CPUs and 16GB of RAM.

Why do some blocks have transactions and no snark work?

While block producers have to add snark work for any transactions they add, in certain cases, if the block producer can, they will include additional snark work. In this example, 124 snarks were included at no cost, and as a result, the next block producers can use these "pre-purchased" snarks to add transactions for free.

Type to search, ESC to discard
Type to search, ESC to discard
Type to search, ESC to discard
  Last updated by Gareth Davies