5.1. Implementation of the Proposed Pool Mining Employing a Modified Ethereum Platform
Architecture of the implemented pool mining is displayed in
Figure 4.
Pool manager implementation consists of two interconnected components: Ethereum client and Pool Manager software (
Figure 4). Ethereum client is used for maintaining the local blockchain copy, for communicating with the network and for creating blocks that are to be mined by the pool. The Pool Manager software is used for distributing the mining jobs to the miners, receiving values that the miners calculate, for looking for the values in the tables, and for completing the mined blocks. Ethereum client used in this implementation is modified Geth client [
19], while the Pool Manager software is based on Open Ethereum Mining Pool [
20].
The miners use a newly implemented software that performs needed calculations for the proposed consensus protocol.
5.1.1. Modified Ethereum Platform
Geth is the current up-to-date implementation of the Ethereum protocol written in the Go programming language. One of the principles of Ethereum is modularity, so Geth already has a certain predefined interface that consists of the following modules:
The Author module returns the Ethereum address of the account that has mined the block with the given header. If the implemented consensus protocol is based on signatures (such as Etherium’s Clique protocol), this address can be differently compared to the address of the coinbase account, which represents the base account of every Ethereum node.
The VerifyHeader module checks whether the header of the new mined block follows the rules of the consensus algorithm that is implemented. This module may check the validity of the crypto seal if the value of its parameter, seal, is set to true, which can also be done explicitly using the VerifySeal module. The module uses argument chain to read the content of the blockchain.
The VerifyHeaders module is similar to that of VerifyHeader. The difference is that this module verifies a series of block headers using the chain reader as the VerifyHeader module does. The module returns two go channels as return values: the quit channel that serves to abort the operations of the module and the result channel that is used to asynchronously transfer the results of the verification, following the order of the blocks in the module’s argument list.
The VerifyUncles module checks the validity of the uncles of the given block. Uncle blocks are blocks that were mined at the same time when the parent of the given block was mined, but have not made it into the blockchain. Those blocks must be valid, as Ethereum protocol stores them and gives some reward to the nodes that mined them. Uncle verification is done in the same way as the verification of other blocks that are part of the blockchain.
The VerifySeal module verifies that the crypto seal of the given block is valid according to the rules of the implemented consensus protocol.
The Prepare module is used to initialize the consensus fields of the block header according to the rules of the implemented consensus protocol.
The Finalize module adds the final values to the block, for example, a reward for finding the block, after the crypto seal value has been added to the block. The result of this module is the block that will be added to the blockchain if the majority of nodes accept it.
The Seal module generates a new block for a given input block with the local miner’s crypto seal, which depends on the block itself, placed on top of it. This is the main module of the consensus algorithm, as its core is the process of mining.
The CalcDifficulty module returns the difficulty of the next block. This adjustment ensures that the time that passes until the new block is added to the blockchain stays always the same or as close as possible.
The APIs module contains RPC API methods that are used by the Pool Manager software to communicate with the client. These methods are used for obtaining mining jobs and sending the newly mined blocks to the client.
The Close module stops every background thread of the consensus protocol and ends it.
According to the above description, a modular decomposition of the Geth Ethereum client is proposed in
Figure 5.
The workflow of Ethereum’s proof-of-work (PoW) algorithm mining procedure is shown in
Figure 6, while the workflow of the verification procedure of the algorithm is shown in
Figure 7.
Recall that the basic Ethereum employs the consensus protocol based on PoW, which operates within the set of modules denoted as “Consensus Modules” in
Figure 5. The main goal is to make the modified Ethereum client employ an alternative consensus protocol that provides flexibility regarding the resources required to execute the protocol. Consequently, framework architecture of the modified Ethereum is proposed which is displayed in
Figure 8: The modified Ethereum is obtained by substitution or modification of certain modules of the traditional Ethereum with those that provide flexibility of resources required for participation in the consensus protocol. The main modifications are performed regarding the following three issues: (i) the puzzle employed instead of PoW; (ii) setting the challenge for the puzzle problem and control of the puzzle solving process; (iii) the verification procedure.
According to the above,
Figure 9 shows which of Ethereum’s consensus modules were modified compared to Ethereum’s PoW algorithm modules.
5.1.2. Modified Open Ethereum Mining Pool
As mentioned earlier, the Pool Manager software is based on Open Ethereum Mining Pool, and runs two threads called network communication thread and miner communication thread.
Network communication thread is used for communicating with the Ethereum client, and through it with the blockchain network. During the operation of the pool, this software periodically sends eth_getWork messages to the Ethereum client, requesting a new mining job. Once the valid response that contains the job is received, Pool Manager software first checks if the current mining job is the same as the one that was received. In cases where the pool has no current job, the mining job received from the client becomes the current job and is sent to the miners as per their request. It may happen, however, that the current mining job already exists, which leads to two possible cases. In the first case, the current mining job is the same as the one that was received, which means that the miners are already working on the up-to-date job, so the PM does not need to do anything. In the second case, the received job is different from the current one, which occurs when a new block is mined in the blockchain network. In that case, the Pool Manager software stores the newly received job, which becomes the new current job that will be distributed to the miners.
Miner communication thread is used for distributing mining jobs to the miners, and to perform task that are specific to the proposed consensus protocol. This thread expects messages from the miners, and once it receives them, it reacts appropriately, by creating a new thread for each message that will be processed. This thread expects three different types of messages:
eth_getWork—this represents a miner’s request for the current mining job of the mining pool. Once the PM receives this request, he first checks if the particular miner is blacklisted due to malicious behavior. If a miner is blacklisted, the PM will ignore his message and do nothing. Otherwise, the PM will send a response to the miner that contains the current mining job, or a message informing the miner that there is no current job, depending on the situation.
tmto_submitValue—this message is used by a miner to send a value that he calculated () in order for the PM to search the tables. Once the PM receives this message, he reads the value that was sent and with a certain probability first checks the correctness of the miner’s work. If the work is found to be correct, the PM checks if the received value can be found in the second column of any of the tables. If the value is found, the PM informs the miner by using the flag and requests the nonce value from the miner in order to complete the block and send it to the network.
tmto_submitSolution—once a miner receives a request from the PM for the nonce value, he uses this message to send it. Upon receiving the nonce value, the PM uses it to find the puzzle solution in the appropriate table row. Once the solution is found, the block is completed and the PM software sends the block to the Ethereum client, where the validity of the block is once again checked, after which the block is broadcasted to the blockchain network.
5.1.3. Pool Miner Implementation
As mentioned above, the miners use a new mining software implemented using Go programming language. The software runs two parallel threads: communication thread and mining thread.
Communication thread is used to communicate with the PM regarding the mining jobs. This thread sends eth_getWork, which was described earlier, in order to obtain the current mining job. If no job is received, the thread will keep sending this message periodically until a job is received. Once a job is received from the PM, the miner must check if the received job is different from the job that the miner is currently working on. If it is, the miner starts working on the received job and abandons the previous one.
Mining thread is the main thread of the mining software that performs the actual mining work. Once a mining job is received by the miner, this thread first randomly selects a nonce value that is needed for the proposed consensus protocol. Afterwards, the miner starts working on the mining job as described in
Table 2. When the miner calculates a new value, he uses the
tmto_submitValue message to send the calculated value to the PM for processing. If the sent value is found in one of the tables located at the PM, the miner is notified and must send the nonce value he selected earlier to the PM so that the block can be completed. The miner uses a
tmto_submitSolution message to send the nonce value to the PM, which effectively completes the mining process for the current mining job, as the PM will complete the block and broadcast it to the blockchain network.
5.2. Algorithms of Pool Mining
Pool mining is based on the following seven algorithms: Algorithms A1–A7. A summary description of these algorithms is given below, and the pseudo-codes of these algorithms are given in
Appendix B. The algorithms are split into two groups: (i) preparation procedure algorithms, Algorithms A1–A3; (ii) mining procedure algorithms, Algorithms A4–A7.
Algorithm A1. The Pool Manager initializes the time–memory table by initializing needed memory, followed by creation of different random numbers, one for the beginning of every row of the table. Once those numbers are created, subsequent elements of every row are calculated by applying the encoding function on the elements that precede them. Once all of the elements are found, only the first and the last column are stored in the TMTO table.
Algorithm A2. A miner sends a request to join the specific mining pool by selecting and sending dimensions of the table that will be ‘rented’ from the pool manager, along with its credentials and identification.
Algorithm A3. The pool manager first checks if the miner who sent the join request is blacklisted. If he is, he is not allowed to join the pool. Otherwise, the pool manager checks the resources for creation of the TMTO table. If he has enough resources, he initializes a table and appends the miner to the pool’s list of miners.
Algorithm A4. The pool manager initializes a new block that is going to be mined by writing various data to the newly created block. Those data include block number, hash of the block’s parent, hash of block’s uncles, and the block’s gas limit. The pool manager also selects and executes transactions from the transaction pool that will become part of the new block.
Algorithm A5. During the mining process, every miner first obtains the block for mining from the pool manager. Afterwards, the miner randomly selects a nonce value, writes it to the block, obtains the block’s hash value, and applies the function to that hash value. The received value represents the starting point for consecutive application of the function. Every new value is obtained by applying this function to the previously obtained value, starting with the result of the function. Once the miner finds a new value, he sends it to the pool manager, who in return checks his TMTO tables for the value. Based on the manager’s response, the miner may abort the mining of the block (response is ), the miner may receive a share as his work was verified (response is ), and the miner may need to send a nonce value to the manager because the value he sent to the pool manager is the one needed to mine the block.
Algorithm A6. The pool manager receives a value from a miner and needs to check if that value is contained in one of his tables. First, however, he checks if the mining work on the current block should continue, as some other miners could have already found the block. If they did, current mining work must be discarded, and the pool manager informs the miner. Otherwise, the pool manager looks for the received value in his tables. If the value is found, the manager stores it to the location where the value was found and informs the miner that he found the solution and that he needs to send his nonce value to the manager. The pool manager may also check the correctness of the miner’s work with a certain probability. If the work is correct, the miner receives a share. If no value was found, the manager informs the miner to continue mining.
Algorithm A7. The pool manager receives the nonce from the miner that is needed to complete the block. The manager firsts finds the location that he stored when he located the value that was sent by the miner previously. The manager now has the required nonce and the location of the value, so he can reconstruct the mining solution by a number of consecutive applications on the encoding function. When the miner finds the solution, he completes the block and publishes it.
The above algorithms show the main procedures of the consensus protocol that is based on two different types of resources and at the same time provides: (i) increased resistance against certain attacks as a consequence of suitable separation of the resources (required for the consensus protocol execution) between the miners and PM; (ii) reduction in the total pool energy required for performing the consensus protocol at the expense of the involvement of certain memory resources. An experimental evaluation of the proposed pool mining approach is given in the next section and it shows the feasibility of the approach. In the considered setting, the PM creates a block that will be the subject of pool miners’ validation attempts and includes the validated block in the blockchain, employing the same approach as in traditional blockchain platforms like Ethereum.
5.3. Experimental Evaluation of Implemented Pool Mining
The experiments were conducted on a platform with an Ubuntu 20.04 operating system that has an Intel Core i7-10750H CPU @2.60 GHz with 12 cores. The goal of the experiment was to show that a malicious miner, who is also a member of the mining pool, will not be able to secretly mine a new block by having a table that he created in local memory and then publish it independently from the pool itself when it is suitable for him. For illustrative purposes, as encryption in the consensus puzzle, a well-known DES (Data Encryption Standard) block cipher is employed. The implemented consensus puzzle is displayed in
Figure 10. Note that the DES has been employed only as a toy example for the puzzle problem that could be considered, because it was the subject of a time–memory trade-off-based cryptanalysis (see reference [
21]). A number of other encryption techniques for which we believe that the time–memory trade-off, or the time–memory-data trade-off are the most efficient attacking approaches can be considered instead of DES. Additionally, we point out that the coding-based encryption schemes discussed in [
22,
23,
24] could be considered as appropriate encryption schemes for the puzzle.
The following conditions were set for execution of the experiments. A private Ethereum network was deployed to measure times needed for mining new blocks. The network ran with only one mining entity active at the same time, which was either the mining pool or the malicious miner. The height of the mining pool table was 11,400,850,688, and its memory size was 17 GiB. The table that the malicious miner kept in secret was the th part of the pool’s table. Its height was 67,108,864, while its size was 1 GiB. A malicious miner can have his own table that he keeps in secret, which can either be a part of the mining pool’s table, or a new table constructed by the malicious miner. During the experiment, the malicious miner used his own table that he constructed in secret. Another thing worth noting is that both the mining pool and the malicious user used the same computing power during mining, which represents the worst-case scenario for the mining pool and the best-case scenario for the malicious miner. However, in reality, this case is highly unlikely to occur, as the members of the mining pool will almost certainly have more cumulative computing power than one single member of the pool. Even if the malicious miner withholds his computing power and does not use it for regular mining in the pool, he just reduces the chance that the pool mines a new block, which in turn reduces the revenue that the pool’s members (including the malicious miner) receive. The difficulty parameter of the mining protocol had the same value throughout the experiment, which ensured that the results received for the mining pool and malicious miner were comparable. Both the mining pool and the malicious miner had the same amount of time (56 h) for mining.
Table 4 shows the experimental results for the mining pool obtained after 56 h of mining. During that time, the mining pool mined 509 new blocks, with the average time needed to find a new block being approximately 393 s. However, the median of times needed for mining a new block was significantly shorter, approximately 290 s, as there were few blocks that required much more time for mining. This can be easily seen from
Figure 11, which shows the distribution of blocks per time needed to mine them.
The histogram shows that more than half of the mined blocks (264 blocks) were mined for 5 min or less, whereas only 48 blocks required more than 15 min to be mined, from which 24 needed more than 20 min.
Table 5 shows the experimental results for the malicious miner obtained after 56 h of mining with the same computing power as the whole mining pool. The first result that is drastically different is the number of blocks mined by the malicious miner, which is only 27. The rest of the results show that the minimum mining time spent finding a block was approximately 168 s, while the average time was approximately 5355 s (close to 1.5 h). It is clear that the malicious miner needed much more mining time to create new blocks than the mining pool.
Figure 12 shows the distribution of blocks per time needed to mine them.
Overall, the results clearly show that even if the malicious miner had the same computing power as the whole mining pool, he would still mine drastically fewer nodes in the same time. Moreover, the maximum mining time for a block by the mining pool is much shorter than the average mining time for a block by the malicious miner. This means that it would be practically impossible for the malicious miner to find a new block and keep it for himself to publish when he finds it suitable.