By Shaun Neal
Due to the massive growth in popularity of Dynamo mining, it became necessary to implement a mining pool. Small solo miners were no longer to mine any substantive number of blocks which was leading to centralization and frustration among early adopters.
Mining pools allow many users to group their mining hashrate together and then share in the proportional rewards. Participants do not get any specific block but rather a percentage of the pool that they participate in. There are many schemes which can be used to divide the pool, however I will only cover the method I used in the dynamo pool.
Source code for the mining pool and mining software as well as pool installation instructions can be found on the Dynamo website at https://www.dynamocoin.org/
When mining solo, a miner connects their software to a full node. The miner requests a block of data to mine and then sets about solving the cryptographic puzzle. Once an answer has been found, the miner submits that to the network for acceptance, and if the miner is the first to solve the puzzle, they are awarded a miner fee.
The mining pool works in between the miner and the full node as a sort of proxy. The steps are generally:
1 — Miner requests pool information, e.g. what the mining pool wallet is, to be used later when assembling the block.
2 — Miner requests a block to mine. This causes the mining pool to request a block from the full node which is relayed to the miner with one small change. The mining pool works on an easier “difficulty” level than the network. As an example, the current network difficulty may be 500. The pool will adjust the difficulty to 50 before sending the block on to the miner.
3 — The miner will set about mining the block at the new lower difficulty and finding a solution. Due to the way the solution is selected (e.g. at random), it is possible that it will be not only under the lower difficulty, but also under the network difficulty. As an example, consider a game of dice where the object is to roll two 6 sized dice under a total of 5. Anyone who rolls a sum of 2, 3 or 4 wins the prize. Now imagine a broker who hires 5 people to roll dice on his behalf. He tells them to roll under an 8. Some of those rolls will also be under 5 and thus the broker will get the prize for some of the rolls. This is the same basis that the mining pool reduced solution works under.
4 — The miner finds a solution and submits it to the pool. The pool records the fact that the miner found a solution and, if the solution is less than the network difficulty, also submits the block to the network for a reward. The reward is paid to the shared pool wallet, not to the miner.
5 — Periodically, the pool checks the shared wallet to see if there are any funds in it. If there are, the funds are divided among the miners based on their share of the blocks submitted. So if there are 2 miners and one submits 40 blocks and the other submits 60 blocks, then they will get a 40/60 split of whatever coins are in the wallet. Of the 100 total blocks submitted, some small number will actually be winning blocks, say 3 — that is the amount that is split 40/60.
I used c# as the language because it is a high level structured language, is cross platform portable and has many third party libraries. I used SQLite as the back end database because it is portable and requires no installation or configuration.
The server is a single executable which runs 2 main threads. The first thread runs an HTTP listener which services incoming RPC requests from miners. For each connection that arrives, a new thread is created and assigned a worker to service the request. The second thread is the distributor. It runs periodically and does the allocation of coins to miners.
The worker thread is fairly simple. It determines which method is being called and takes the appropriate action. In some cases the pool can service the request directly, in others it must interact with the full node. A simple webclient interface is used to connect to the full node.
The distributor is also fairly straightforward. It compares the current time to the last run time and interval and decides when it needs to execute. On execution it checks the shared wallet balance via RPC call, and if non-zero, sums up the shares for all miners and distributes them, again via RPC calls.
The main complexity in the pool design was the replication of the Dynamo proof of work algorithm. This was previously created using C++, so it had to be ported to C#, which was quite time consuming due to all of the byte order issues.
The dynamo pool is a simple yet fully functioning mining pool server which can be used by pool operators as a starting point for more robust commercial mining pool services.