-
Notifications
You must be signed in to change notification settings - Fork 863
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Adds GPU Mining #14
Changes from 2 commits
a166514
9b4d34a
82fa88a
328bc8e
7aa19a3
c8ad419
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# Besu GPU Mining | ||
|
||
## Mining Software | ||
|
||
EthMiner is recommended. You can [download EthMiner from Github](https://github.com/ethereum-mining/ethminer), available for Windows, Linux, and MacOS. | ||
|
||
## GPU Mining with Besu | ||
|
||
To mine with EthMiner, start Besu with HTTP RPC enabled, setting cors to the IP of the miners you want mining from Besu. | ||
|
||
If running in a development environment, the starting flags would be the following: | ||
|
||
``` | ||
./bin/besu --network=dev --gpu-mining-enabled --rpc-http-enabled --rpc-http-cors-origins=all | ||
``` | ||
|
||
This starts Besu in a developer network with JSON RPC available at localhost:8545, with cors set to all IPs. | ||
|
||
Once initiated, you must wait until work is available before starting EthMiner. Once work is availabe, start EthMiner pointing to the JSON RPC endpoint. From the directory containing EthMiner: | ||
|
||
``` | ||
<EthMiner> -P http://<Your Ethereum Address>@<Host>:<Port> | ||
``` | ||
|
||
An example on Windows would look like the following: | ||
|
||
``` | ||
ethminer.exe -P http://0xBBAac64b4E4499aa40DB238FaA8Ac00BAc50811B@127.0.0.1:8545 | ||
``` | ||
|
||
Other computers can mine to this Besu node if cors allows it, by setting the host to the IP of the computer/server running Besu, or the hostname of the server running Besu. | ||
|
||
You can test when work is available using CURL in a command line: | ||
|
||
``` | ||
curl -X POST --data "{"jsonrpc":"2.0","method":"eth_getWork","params":[],"id":73}" localhost:8545 | ||
``` | ||
|
||
From Windows Command Prompt, qoutes are special characters. | ||
|
||
``` | ||
curl -X POST --data "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getWork\",\"params\":[],\"id\":73}" localhost:8545 | ||
``` | ||
|
||
If work is available for mining, you should see a response similar to the following: | ||
|
||
``` | ||
{"jsonrpc":"2.0","id":73,"result":["0xc9a815cfff9186b3b1ebb286ff71156b2605c4ca45e2413418c8054688011706","0x0000000000000000000000000000000000000000000000000000000000000000","0x028f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f"]} | ||
``` | ||
|
||
If EthMiner disappears after building or downloading, check with your anti-virus software, allow EthMiner to run, and redownload. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,6 +33,8 @@ public class EthGetWork implements JsonRpcMethod { | |
|
||
private final MiningCoordinator miner; | ||
private static final Logger LOG = getLogger(); | ||
private Boolean solverWasPresent = false; | ||
private String[] storedResult; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't store the stored result in the RPC method, query it from the mining co-ordinator. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mining coordinator doesn't store previous results. In-between results, there would be cases where |
||
|
||
public EthGetWork(final MiningCoordinator miner) { | ||
this.miner = miner; | ||
|
@@ -54,7 +56,11 @@ public JsonRpcResponse response(final JsonRpcRequest req) { | |
"0x" + BaseEncoding.base16().lowerCase().encode(dagSeed), | ||
rawResult.getTarget().toHexString() | ||
}; | ||
solverWasPresent = true; | ||
storedResult = result; | ||
return new JsonRpcSuccessResponse(req.getId(), result); | ||
} else if (solverWasPresent) { | ||
return new JsonRpcSuccessResponse(req.getId(), storedResult); | ||
} else { | ||
LOG.trace("Mining is not operational, eth_getWork request cannot be processed"); | ||
return new JsonRpcErrorResponse(req.getId(), JsonRpcError.NO_MINING_WORK_FOUND); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* Copyright 2018 ConsenSys AG. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on | ||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations under the License. | ||
*/ | ||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; | ||
|
||
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; | ||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; | ||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; | ||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; | ||
|
||
public class EthSubmitLogin implements JsonRpcMethod { | ||
|
||
@Override | ||
public String getName() { | ||
return RpcMethod.ETH_SUBMIT_LOGIN.getMethodName(); | ||
} | ||
|
||
@Override | ||
public JsonRpcResponse response(final JsonRpcRequest req) { | ||
// Confirm login request | ||
boolean result = true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this just a stub or should there be more logic here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mining pools use this route to add a miner to their database for purposes such as withholding payouts until a certain threshold is met, collecting fees, and notifying users by email when a miner becomes inactive, while notifying mining software that connection has been established. Here, we're simply accepting all mining software connection requests, notifying mining software connection has been established. |
||
return new JsonRpcSuccessResponse(req.getId(), result); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,6 +54,7 @@ public class BlockMiner<C, M extends AbstractBlockCreator<C>> implements Runnabl | |
private final ProtocolSchedule<C> protocolSchedule; | ||
private final Subscribers<MinedBlockObserver> observers; | ||
private final AbstractBlockScheduler scheduler; | ||
private Boolean gpuMining = false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't call it GPU mining, call it |
||
|
||
public BlockMiner( | ||
final Function<BlockHeader, M> blockCreatorFactory, | ||
|
@@ -109,6 +110,11 @@ public Block createBlock( | |
return blockCreator.createBlock(transactions, ommers, timestamp); | ||
} | ||
|
||
public void setGpuMining() { | ||
gpuMining = true; | ||
return; | ||
} | ||
|
||
protected boolean mineBlock() throws InterruptedException { | ||
// Ensure the block is allowed to be mined - i.e. the timestamp on the new block is sufficiently | ||
// ahead of the parent, and still within allowable clock tolerance. | ||
|
@@ -123,28 +129,41 @@ protected boolean mineBlock() throws InterruptedException { | |
"Block created, importing to local chain, block includes {} transactions", | ||
block.getBody().getTransactions().size()); | ||
|
||
final BlockImporter<C> importer = | ||
protocolSchedule.getByBlockNumber(block.getHeader().getNumber()).getBlockImporter(); | ||
final boolean blockImported = | ||
importer.importBlock(protocolContext, block, HeaderValidationMode.FULL); | ||
if (blockImported) { | ||
notifyNewBlockListeners(block); | ||
final double taskTimeInSec = stopwatch.elapsed(TimeUnit.MILLISECONDS) / 1000.0; | ||
if (gpuMining) { | ||
LOG.info( | ||
String.format( | ||
"Produced and imported block #%,d / %d tx / %d om / %,d (%01.1f%%) gas / (%s) in %01.3fs", | ||
block.getHeader().getNumber(), | ||
block.getBody().getTransactions().size(), | ||
block.getBody().getOmmers().size(), | ||
block.getHeader().getGasUsed(), | ||
(block.getHeader().getGasUsed() * 100.0) / block.getHeader().getGasLimit(), | ||
block.getHash(), | ||
taskTimeInSec)); | ||
String.format( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is formatted incorrectly. |
||
"Produced block #%,d / %d tx / %d om / %,d (%01.1f%%) gas / (%s) ", | ||
block.getHeader().getNumber(), | ||
block.getBody().getTransactions().size(), | ||
block.getBody().getOmmers().size(), | ||
block.getHeader().getGasUsed(), | ||
(block.getHeader().getGasUsed() * 100.0) / block.getHeader().getGasLimit(), | ||
block.getHash())); | ||
return false; | ||
} else { | ||
LOG.error("Illegal block mined, could not be imported to local chain."); | ||
} | ||
final BlockImporter<C> importer = | ||
protocolSchedule.getByBlockNumber(block.getHeader().getNumber()).getBlockImporter(); | ||
final boolean blockImported = | ||
importer.importBlock(protocolContext, block, HeaderValidationMode.FULL); | ||
if (blockImported) { | ||
notifyNewBlockListeners(block); | ||
final double taskTimeInSec = stopwatch.elapsed(TimeUnit.MILLISECONDS) / 1000.0; | ||
LOG.info( | ||
String.format( | ||
"Produced and imported block #%,d / %d tx / %d om / %,d (%01.1f%%) gas / (%s) in %01.3fs", | ||
block.getHeader().getNumber(), | ||
block.getBody().getTransactions().size(), | ||
block.getBody().getOmmers().size(), | ||
block.getHeader().getGasUsed(), | ||
(block.getHeader().getGasUsed() * 100.0) / block.getHeader().getGasLimit(), | ||
block.getHash(), | ||
taskTimeInSec)); | ||
} else { | ||
LOG.error("Illegal block mined, could not be imported to local chain."); | ||
} | ||
|
||
return blockImported; | ||
return blockImported; | ||
} | ||
} | ||
|
||
public void cancel() { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not need to be an if block with two clauses. Used a
?:
statement, but the odds are it won't be needed as mining will still need a coinbase and not an address of zero.