/chainweb-miner

Official mining software for the Kadena Public Blockchain.

Primary LanguageHaskellBSD 3-Clause "New" or "Revised" LicenseBSD-3-Clause

Mining for the Kadena Public Blockchain

IMPORTANT NOTE: chainweb-miner is deprecated. Please use chainweb-mining-client instead.

Table of Contents

What is Mining?

A blockchain is a series of blocks. Blocks contain transactions that represent coin transfers or other Smart Contract interactions. Mining is the process of mathematically “solving” a block. Unless solved, a block cannot be included in the chain. Without mining, a blockchain cannot progress and transactions will never finalize.

Economically, mining is the principal way to obtain currency on the Kadena network. Since we use Proof-of-Work, computational effort is rewarded with coins associated with each block you solve. The more computational power you have, the more likely you are to be successful at mining.

Unlike blockchains that have a single chain, ours has many parallel chains. Everyone who chooses to mine can spread their effort across these multiple chains, advancing each one equally, thereby reducing competition and wasted effort.

Mining via Official Kadena Software

We recommend chainweb-miner, our dedicated Mining Client. Work requests are sent to known Nodes, which construct blocks for the client. Once solved, the client returns the block to the Node for submission to the wider network.

You will need a Key Pair before beginning.

Obtaining a Key Pair

The easiest way to obtain a Key Pair is via the chainweb-miner keys command. Once generated, please be very careful to save the public and secret (private) keys because you don’t want to lose them.

The first time you mine a block with your key pair an account is created for you. You can use any account name that doesn’t yet exist. It is recommended to use public key of your key pair as account name.

Mining with chainweb-miner

CPU Mining

chainweb-miner cpu --cores=4 --node=<trusted-node>:443 --miner-account=<you> --miner-key=<your-public-key>

The list of trusted nodes can be found here.

Things to note:

  • You can dedicate as many cores to parallel mining as you want with --cores.
  • If specifying the number of cores, the --cores flag must follow directly after the cpu flag.
  • When --cores is omitted during CPU mining, then the number of cores used will default to 1.
  • You can only communicate with one Node at a time.
  • As stated above, your declared account must be owned by you, or your rewards will likely be lost.

GPU Mining

We also provide a GPU Miner which integrates with chainweb-miner. Installation and usage instructions can found here.

Chain Focusing

You might have a reason to prioritize one chain over the rest. To request that the Node attempt to give you work for a specific chain first, pass --chain:

./chainweb-miner cpu --chain=9 ... # other flags

Log Suppression

You may only be interested in warning or error messages. If so, use the --log-level flag:

chainweb-miner cpu --log-level=warn ... # other flags
2019-09-16 16:57:56.755636: [warn] Couldn't connect to update stream. Trying again...
2019-09-16 16:58:23.646547: [error] Failed to fetch work! Is the Node down?

Specifying Multiple Nodes

You can specify multiple nodes to mine from the command line. However, what this actually means needs to be clarified. Consider this example:

./chainweb-miner cpu --node=us-e3.chainweb.com:443
--node=us-e2.chainweb.com:443 ...

Before discussing the aforementioned necessary clarification, note that specifying multiple nodes is rather straightforward: just add another --node= clause (as found in the example)! Now, when you specify multiple nodes to mine, this does not mean that the first block you mine is from us-e3.chainweb.com while the second is from us-e2.chainweb.com. Instead, the first node found on the command line is the first node the chainweb-miner attempts to communicate with to find blocks to mine. If for some reason, the chainweb-miner is unable to establish a connection with the node, then it will attempt to establish a connection with the specified next node. This process will continue until there are no more nodes left to consider. Upon this event, the chainweb-miner process will halt and exit. For example, given the above example, if the chainweb-miner cannot communicate with either us-e3.chainweb or us-e2.chainweb.com, then the process terminates.

Also, the first node specified from the left is the first node that chainweb-miner attempts to form a communication channel to get blocks to mine.

Balance Lookup

Given a node url, you can check the balance of a given miner acccount with the chainweb-miner tool. Let’s look at this example:

./chainweb-miner balance-check --node=us-w2.chainweb.com:443 --miner-account exampleaccount

Drawing upon this example, you are allowed to only query one node and you must specify the miner account. This feature will automatically query your balance on all nodes and also print the total amount across all chains. Here is some example output:

The balance on chain 0 is 39.176891.
The balance on chain 1 is 69.13569.
The balance on chain 2 is 69.13569.
The balance on chain 3 is 53.004029.
The balance on chain 4 is 57.613075.
The balance on chain 5 is 76.049259.
The balance on chain 6 is 53.004029.
The balance on chain 7 is 50.699506.
The balance on chain 8 is 64.526644.
The balance on chain 9 is 48.394983.
Your total is 580.739796000000

We recommend querying your balance from the node you have been mining to as well as a couple other nodes (i.e. the bootstrap nodes).

Troubleshooting

I mined using the wrong account name and/or public key!

Your coins are likely gone.

Your KeyNot Your Key
Your AccountHurray!Work rejected by Node.
Not Your AccountWork rejected by Node.Work rejected by Node.
Non-existant AccountYou own a new account!Coins locked forever.

chainweb-miner says that I mined, but I didn’t receive the reward.

This?

2019-09-16 16:58:37.289252: [info] Chain 6: Mined block at Height 12440.

And yet your balance on Chain 6 remains unchanged?

Mining is a big race. Even if you succeeded on Chain 6, by the time your block returned to the Node, the Node may have already registered a faster block.

But if it knew about a better block on my chain, why didn’t it preempt me?

Race conditions. There’s a small time window between the Node processing the faster block, telling you about it, and you submitting your own block. Consider it bad luck.

I specify --chain=... but am getting work for other chains. Why?

It is fundamental to the design of a Chainweb network that chains cannot progress much further than their neighbor chains. It may be that by asking for --chain=9, the Node couldn’t find work to do! In this case, it falls back to picking a random chain. This balances the needs of the Miner, who may want a specific Chain to progress efficiently, with the needs of the network, which requires all chains to grow evenly.

Why am I being “preempted” so much?

This?

2019-09-16 17:30:11.791641: [debug] Chain 7: Current work was preempted.
2019-09-16 17:30:15.759249: [debug] Chain 8: Current work was preempted.
2019-09-16 17:30:27.340109: [debug] Chain 9: Current work was preempted.
2019-09-16 17:30:57.343577: [debug] Chain 6: Current work was preempted.
2019-09-16 17:31:04.998382: [debug] Chain 9: Current work was preempted.
2019-09-16 17:31:14.649440: [debug] Chain 1: Current work was preempted.
2019-09-16 17:31:25.503355: [debug] Chain 4: Current work was preempted.
2019-09-16 17:31:45.471371: [debug] Chain 9: Current work was preempted.
2019-09-16 17:31:56.940698: [debug] Chain 2: Current work was preempted.
2019-09-16 17:32:16.807348: [debug] Chain 9: Current work was preempted.
2019-09-16 17:32:21.721842: [debug] Chain 8: Current work was preempted.

This is normal. This means that other miners are beating you, and that you probably don’t hold much of the overall network hash power.

Remote API Details

A chainweb-miner communicates with a chainweb-node via the following endpoints.

Work Requests

Intent: I want a new BlockHeader to mine on.

GET /chainweb/0.0/mainnet01/mining/work?chain=...

Clients can optionally specify a Chain to “focus” on.

Request Body (JSON):

{
    "account": "miner",
    "predicate": "keys-all",
    "public-keys": [
        "f880a433d6e2a13a32b6169030f56245efdd8c1b8a5027e9ce98a88e886bef27"
    ]
}

Response (Octet Stream):

Work Bytes - 322 bytes

ChainBytes(4) + TargetBytes(32) + HeaderBytes(286)

The minimum information required to perform Proof-of-Work. No knowledge of
Chainweb internals is necessary.
PieceDescription
ChainBytesThe final chain selection made by the Node.
TargetBytesEncoded form of the current Hash Target.
HeaderBytesEncoded form of the Block Header.

Solution Submission

Intent: I solved a block - here it is.

POST /chainweb/0.0/mainnet01/mining/solved

Request Body (Octet Stream):

Header Bytes - 286 bytes

The original work received, updated internally with the Nonce that satisfies the
Proof-of-Work.

Update Subscription

Intent: I am currently mining. Is the work I’m doing still worth it?

GET /chainweb/0.0/mainnet01/mining/updates

Request Body (Octet Stream):

Chain Bytes - 4 bytes

The first 4 bytes received from a call to /mining/work. This tells the Node to
only inform the Miner of a new Cut when the specific chain in question has
updated.

Response (Server-Sent Event):

A stream of Server-Sent Events with a single line:

event:New Cut