Skip to content
This repository has been archived by the owner on May 29, 2020. It is now read-only.

Commit

Permalink
[NC-1384] Disable mining while catching up to chain head (PegaSysEng#125
Browse files Browse the repository at this point in the history
)
  • Loading branch information
ajsutton authored Oct 24, 2018
1 parent ba18fcf commit d2583e3
Show file tree
Hide file tree
Showing 65 changed files with 629 additions and 141 deletions.
1 change: 1 addition & 0 deletions acceptance-tests/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ dependencies {
testImplementation project(':crypto')
testImplementation project(':ethereum:eth')
testImplementation project(':ethereum:core')
testImplementation project(':ethereum:blockcreation')
testImplementation project(':ethereum:jsonrpc')
testImplementation project(':pantheon')
testImplementation project(':util')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import tech.pegasys.pantheon.controller.KeyPairUtil;
import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair;
import tech.pegasys.pantheon.ethereum.blockcreation.MiningParameters;
import tech.pegasys.pantheon.ethereum.core.MiningParameters;
import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration;
import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration;
import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*/
package tech.pegasys.pantheon.tests.acceptance.dsl.node;

import tech.pegasys.pantheon.ethereum.blockcreation.MiningParameters;
import tech.pegasys.pantheon.ethereum.core.MiningParameters;
import tech.pegasys.pantheon.ethereum.core.MiningParametersTestBuilder;
import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration;
import tech.pegasys.pantheon.ethereum.jsonrpc.RpcApi;
Expand Down
1 change: 1 addition & 0 deletions consensus/clique/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ repositories { mavenCentral() }
dependencies {
implementation project(':crypto')
implementation project(':ethereum:core')
implementation project(':ethereum:blockcreation')
implementation project(':ethereum:eth')
implementation project(':ethereum:jsonrpc')
implementation project(':ethereum:rlp')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
import tech.pegasys.pantheon.consensus.clique.CliqueHelpers;
import tech.pegasys.pantheon.ethereum.ProtocolContext;
import tech.pegasys.pantheon.ethereum.blockcreation.AbstractBlockScheduler;
import tech.pegasys.pantheon.ethereum.blockcreation.AbstractMiningCoordinator.MinedBlockObserver;
import tech.pegasys.pantheon.ethereum.blockcreation.BlockMiner;
import tech.pegasys.pantheon.ethereum.chain.MinedBlockObserver;
import tech.pegasys.pantheon.ethereum.core.Address;
import tech.pegasys.pantheon.ethereum.core.BlockHeader;
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@
import tech.pegasys.pantheon.ethereum.ProtocolContext;
import tech.pegasys.pantheon.ethereum.blockcreation.AbstractBlockScheduler;
import tech.pegasys.pantheon.ethereum.blockcreation.AbstractMinerExecutor;
import tech.pegasys.pantheon.ethereum.blockcreation.AbstractMiningCoordinator.MinedBlockObserver;
import tech.pegasys.pantheon.ethereum.blockcreation.MiningParameters;
import tech.pegasys.pantheon.ethereum.chain.MinedBlockObserver;
import tech.pegasys.pantheon.ethereum.core.Address;
import tech.pegasys.pantheon.ethereum.core.BlockHeader;
import tech.pegasys.pantheon.ethereum.core.MiningParameters;
import tech.pegasys.pantheon.ethereum.core.PendingTransactions;
import tech.pegasys.pantheon.ethereum.core.Util;
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,13 @@
import tech.pegasys.pantheon.consensus.clique.CliqueContext;
import tech.pegasys.pantheon.ethereum.blockcreation.AbstractMiningCoordinator;
import tech.pegasys.pantheon.ethereum.chain.Blockchain;

import java.util.Optional;
import tech.pegasys.pantheon.ethereum.eth.sync.state.SyncState;

public class CliqueMiningCoordinator
extends AbstractMiningCoordinator<CliqueContext, CliqueBlockMiner> {

public CliqueMiningCoordinator(final Blockchain blockchain, final CliqueMinerExecutor executor) {
super(blockchain, executor);
}

@Override
protected void haltCurrentMiningOperation() {
currentRunningMiner.ifPresent(CliqueBlockMiner::cancel);
currentRunningMiner = Optional.empty();
public CliqueMiningCoordinator(
final Blockchain blockchain, final CliqueMinerExecutor executor, final SyncState syncState) {
super(blockchain, executor, syncState);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@
import tech.pegasys.pantheon.consensus.common.VoteTally;
import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair;
import tech.pegasys.pantheon.ethereum.ProtocolContext;
import tech.pegasys.pantheon.ethereum.blockcreation.MiningParameters;
import tech.pegasys.pantheon.ethereum.core.Address;
import tech.pegasys.pantheon.ethereum.core.AddressHelpers;
import tech.pegasys.pantheon.ethereum.core.BlockHeader;
import tech.pegasys.pantheon.ethereum.core.BlockHeaderTestFixture;
import tech.pegasys.pantheon.ethereum.core.MiningParameters;
import tech.pegasys.pantheon.ethereum.core.PendingTransactions;
import tech.pegasys.pantheon.ethereum.core.Util;
import tech.pegasys.pantheon.ethereum.core.Wei;
Expand Down
1 change: 1 addition & 0 deletions consensus/ibft/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ dependencies {
implementation project(':consensus:common')
implementation project(':crypto')
implementation project(':ethereum:core')
implementation project(':ethereum:blockcreation')
implementation project(':ethereum:eth')
implementation project(':ethereum:jsonrpc')
implementation project(':ethereum:rlp')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
import tech.pegasys.pantheon.consensus.ibft.IbftContext;
import tech.pegasys.pantheon.ethereum.ProtocolContext;
import tech.pegasys.pantheon.ethereum.blockcreation.AbstractBlockScheduler;
import tech.pegasys.pantheon.ethereum.blockcreation.AbstractMiningCoordinator.MinedBlockObserver;
import tech.pegasys.pantheon.ethereum.blockcreation.BlockMiner;
import tech.pegasys.pantheon.ethereum.chain.MinedBlockObserver;
import tech.pegasys.pantheon.ethereum.core.BlockHeader;
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule;
import tech.pegasys.pantheon.util.Subscribers;
Expand Down
1 change: 1 addition & 0 deletions consensus/ibftlegacy/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ dependencies {
implementation project(':consensus:ibft')
implementation project(':crypto')
implementation project(':ethereum:core')
implementation project(':ethereum:blockcreation')
implementation project(':ethereum:eth')
implementation project(':ethereum:jsonrpc')
implementation project(':ethereum:rlp')
Expand Down
27 changes: 27 additions & 0 deletions ethereum/blockcreation/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
apply plugin: 'java-library'

jar {
baseName 'pantheon-blockcreation'
manifest {
attributes('Implementation-Title': baseName,
'Implementation-Version': project.version)
}
}

dependencies {
implementation project(':ethereum:core')
implementation project(':ethereum:eth')
implementation project(':util')
implementation project(':crypto')
implementation project(':services:kvstore')

implementation 'io.vertx:vertx-core'
implementation 'com.google.guava:guava'

testImplementation 'junit:junit'
testImplementation 'org.assertj:assertj-core'
testImplementation 'org.awaitility:awaitility'
testImplementation 'org.mockito:mockito-core'
testImplementation project(path: ':ethereum:core', configuration: 'testSupportArtifacts')
testImplementation project(path: ':ethereum:core', configuration: 'testArtifacts')
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
package tech.pegasys.pantheon.ethereum.blockcreation;

import tech.pegasys.pantheon.ethereum.ProtocolContext;
import tech.pegasys.pantheon.ethereum.blockcreation.AbstractMiningCoordinator.MinedBlockObserver;
import tech.pegasys.pantheon.ethereum.chain.MinedBlockObserver;
import tech.pegasys.pantheon.ethereum.core.BlockHeader;
import tech.pegasys.pantheon.ethereum.core.MiningParameters;
import tech.pegasys.pantheon.ethereum.core.PendingTransactions;
import tech.pegasys.pantheon.ethereum.core.Wei;
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,45 +12,56 @@
*/
package tech.pegasys.pantheon.ethereum.blockcreation;

import static org.apache.logging.log4j.LogManager.getLogger;

import tech.pegasys.pantheon.ethereum.chain.BlockAddedEvent;
import tech.pegasys.pantheon.ethereum.chain.BlockAddedEvent.EventType;
import tech.pegasys.pantheon.ethereum.chain.BlockAddedObserver;
import tech.pegasys.pantheon.ethereum.chain.Blockchain;
import tech.pegasys.pantheon.ethereum.chain.MinedBlockObserver;
import tech.pegasys.pantheon.ethereum.core.Address;
import tech.pegasys.pantheon.ethereum.core.Block;
import tech.pegasys.pantheon.ethereum.core.BlockHeader;
import tech.pegasys.pantheon.ethereum.core.Wei;
import tech.pegasys.pantheon.ethereum.eth.sync.state.SyncState;
import tech.pegasys.pantheon.ethereum.mainnet.EthHashSolution;
import tech.pegasys.pantheon.ethereum.mainnet.EthHashSolverInputs;
import tech.pegasys.pantheon.util.Subscribers;
import tech.pegasys.pantheon.util.bytes.BytesValue;

import java.util.Optional;

import org.apache.logging.log4j.Logger;

public abstract class AbstractMiningCoordinator<
C, M extends BlockMiner<C, ? extends AbstractBlockCreator<C>>>
implements BlockAddedObserver {

private static final Logger LOG = getLogger();
protected boolean isEnabled = false;
protected volatile Optional<M> currentRunningMiner = Optional.empty();

private final Subscribers<MinedBlockObserver> minedBlockObservers = new Subscribers<>();
private final AbstractMinerExecutor<C, M> executor;
protected final Blockchain blockchain;
private final SyncState syncState;

public AbstractMiningCoordinator(
final Blockchain blockchain, final AbstractMinerExecutor<C, M> executor) {
final Blockchain blockchain,
final AbstractMinerExecutor<C, M> executor,
final SyncState syncState) {
this.executor = executor;
this.blockchain = blockchain;
this.syncState = syncState;
this.blockchain.observeBlockAdded(this);
syncState.addInSyncListener(this::inSyncChanged);
}

public void enable() {
synchronized (this) {
if (isEnabled) {
return;
}
startAsyncMiningOperation();
if (syncState.isInSync()) {
startAsyncMiningOperation();
}
isEnabled = true;
}
}
Expand All @@ -67,7 +78,7 @@ public void disable() {

public boolean isRunning() {
synchronized (this) {
return isEnabled;
return currentRunningMiner.isPresent();
}
}

Expand All @@ -78,28 +89,35 @@ protected void startAsyncMiningOperation() {

protected void haltCurrentMiningOperation() {
currentRunningMiner.ifPresent(M::cancel);
currentRunningMiner = Optional.empty();
}

@Override
public void onBlockAdded(final BlockAddedEvent event, final Blockchain blockchain) {
synchronized (this) {
if (isEnabled && shouldStartNewMiner(event)) {
if (isEnabled && event.isNewCanonicalHead()) {
haltCurrentMiningOperation();
startAsyncMiningOperation();
if (syncState.isInSync()) {
startAsyncMiningOperation();
}
}
}
}

private boolean shouldStartNewMiner(final BlockAddedEvent event) {
return event.getEventType() != EventType.FORK;
}

public void removeMinedBlockObserver(final long id) {
minedBlockObservers.unsubscribe(id);
public void inSyncChanged(final boolean inSync) {
synchronized (this) {
if (isEnabled && inSync) {
LOG.info("Resuming mining operations");
startAsyncMiningOperation();
} else if (!inSync) {
LOG.info("Pausing mining while behind chain head");
haltCurrentMiningOperation();
}
}
}

public long addMinedBlockObserver(final MinedBlockObserver obs) {
return minedBlockObservers.subscribe(obs);
public void addMinedBlockObserver(final MinedBlockObserver obs) {
minedBlockObservers.subscribe(obs);
}

// Required for JSON RPC, and are deemed to be valid for all mining mechanisms
Expand All @@ -117,31 +135,26 @@ public void setExtraData(final BytesValue extraData) {

public void setCoinbase(final Address coinbase) {
throw new UnsupportedOperationException(
"Current consensus mechanism prevents" + " setting coinbase.");
"Current consensus mechanism prevents setting coinbase.");
}

public Optional<Address> getCoinbase() {
throw new UnsupportedOperationException(
"Current consensus mechanism prevents" + " querying of coinbase.");
"Current consensus mechanism prevents querying of coinbase.");
}

public Optional<Long> hashesPerSecond() {
throw new UnsupportedOperationException(
"Current consensus mechanism prevents querying " + "of hashrate.");
"Current consensus mechanism prevents querying of hashrate.");
}

public Optional<EthHashSolverInputs> getWorkDefinition() {
throw new UnsupportedOperationException(
"Current consensus mechanism prevents querying " + "work definition.");
"Current consensus mechanism prevents querying work definition.");
}

public boolean submitWork(final EthHashSolution solution) {
throw new UnsupportedOperationException(
"Current consensus mechanism prevents submission of work" + " solutions.");
}

public interface MinedBlockObserver {

void blockMined(Block block);
"Current consensus mechanism prevents submission of work solutions.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
package tech.pegasys.pantheon.ethereum.blockcreation;

import tech.pegasys.pantheon.ethereum.ProtocolContext;
import tech.pegasys.pantheon.ethereum.blockcreation.AbstractMiningCoordinator.MinedBlockObserver;
import tech.pegasys.pantheon.ethereum.chain.MinedBlockObserver;
import tech.pegasys.pantheon.ethereum.core.Block;
import tech.pegasys.pantheon.ethereum.core.BlockHeader;
import tech.pegasys.pantheon.ethereum.core.BlockImporter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,22 @@
* 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 tech.pegasys.pantheon.ethereum.mainnet;
package tech.pegasys.pantheon.ethereum.blockcreation;

import tech.pegasys.pantheon.ethereum.ProtocolContext;
import tech.pegasys.pantheon.ethereum.blockcreation.AbstractBlockCreator;
import tech.pegasys.pantheon.ethereum.core.Address;
import tech.pegasys.pantheon.ethereum.core.BlockHeader;
import tech.pegasys.pantheon.ethereum.core.BlockHeaderBuilder;
import tech.pegasys.pantheon.ethereum.core.PendingTransactions;
import tech.pegasys.pantheon.ethereum.core.SealableBlockHeader;
import tech.pegasys.pantheon.ethereum.core.Wei;
import tech.pegasys.pantheon.ethereum.mainnet.EthHash;
import tech.pegasys.pantheon.ethereum.mainnet.EthHashSolution;
import tech.pegasys.pantheon.ethereum.mainnet.EthHashSolver;
import tech.pegasys.pantheon.ethereum.mainnet.EthHashSolver.EthHashSolverJob;
import tech.pegasys.pantheon.ethereum.mainnet.EthHashSolverInputs;
import tech.pegasys.pantheon.ethereum.mainnet.MainnetBlockHashFunction;
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule;
import tech.pegasys.pantheon.util.bytes.BytesValues;
import tech.pegasys.pantheon.util.uint.UInt256;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@
package tech.pegasys.pantheon.ethereum.blockcreation;

import tech.pegasys.pantheon.ethereum.ProtocolContext;
import tech.pegasys.pantheon.ethereum.blockcreation.AbstractMiningCoordinator.MinedBlockObserver;
import tech.pegasys.pantheon.ethereum.chain.MinedBlockObserver;
import tech.pegasys.pantheon.ethereum.core.BlockHeader;
import tech.pegasys.pantheon.ethereum.mainnet.EthHashBlockCreator;
import tech.pegasys.pantheon.ethereum.mainnet.EthHashSolution;
import tech.pegasys.pantheon.ethereum.mainnet.EthHashSolverInputs;
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
package tech.pegasys.pantheon.ethereum.blockcreation;

import tech.pegasys.pantheon.ethereum.ProtocolContext;
import tech.pegasys.pantheon.ethereum.blockcreation.AbstractMiningCoordinator.MinedBlockObserver;
import tech.pegasys.pantheon.ethereum.chain.MinedBlockObserver;
import tech.pegasys.pantheon.ethereum.core.Address;
import tech.pegasys.pantheon.ethereum.core.BlockHeader;
import tech.pegasys.pantheon.ethereum.core.MiningParameters;
import tech.pegasys.pantheon.ethereum.core.PendingTransactions;
import tech.pegasys.pantheon.ethereum.mainnet.EthHashBlockCreator;
import tech.pegasys.pantheon.ethereum.mainnet.EthHashSolver;
import tech.pegasys.pantheon.ethereum.mainnet.EthHasher;
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import tech.pegasys.pantheon.ethereum.chain.BlockAddedObserver;
import tech.pegasys.pantheon.ethereum.chain.Blockchain;
import tech.pegasys.pantheon.ethereum.core.Address;
import tech.pegasys.pantheon.ethereum.eth.sync.state.SyncState;
import tech.pegasys.pantheon.ethereum.mainnet.EthHashSolution;
import tech.pegasys.pantheon.ethereum.mainnet.EthHashSolverInputs;

Expand All @@ -31,8 +32,8 @@ public class EthHashMiningCoordinator extends AbstractMiningCoordinator<Void, Et
private volatile Optional<Long> cachedHashesPerSecond = Optional.empty();

public EthHashMiningCoordinator(
final Blockchain blockchain, final EthHashMinerExecutor executor) {
super(blockchain, executor);
final Blockchain blockchain, final EthHashMinerExecutor executor, final SyncState syncState) {
super(blockchain, executor, syncState);
this.executor = executor;
}

Expand Down Expand Up @@ -78,5 +79,6 @@ protected void haltCurrentMiningOperation() {
miner.cancel();
miner.getHashesPerSecond().ifPresent(val -> cachedHashesPerSecond = Optional.of(val));
});
currentRunningMiner = Optional.empty();
}
}
Loading

0 comments on commit d2583e3

Please sign in to comment.