diff --git a/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueVotingBlockInterface.java b/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueVotingBlockInterface.java index 19d8fa4c5f..3ee90324f5 100644 --- a/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueVotingBlockInterface.java +++ b/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueVotingBlockInterface.java @@ -52,8 +52,7 @@ public class CliqueVotingBlockInterface implements VoteBlockInterface { return Optional.empty(); } - @Override - public BlockHeaderBuilder insertVoteToHeaderBuilder( + public static BlockHeaderBuilder insertVoteToHeaderBuilder( final BlockHeaderBuilder builder, final Optional vote) { if (vote.isPresent()) { final ValidatorVote voteToCast = vote.get(); diff --git a/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueBlockCreator.java b/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueBlockCreator.java index 7d962397ed..82391046b0 100644 --- a/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueBlockCreator.java +++ b/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueBlockCreator.java @@ -40,8 +40,6 @@ import java.util.function.Function; public class CliqueBlockCreator extends AbstractBlockCreator { private final KeyPair nodeKeys; - private static final CliqueVotingBlockInterface votingInterface = - new CliqueVotingBlockInterface(); public CliqueBlockCreator( final Address coinbase, @@ -93,9 +91,11 @@ public class CliqueBlockCreator extends AbstractBlockCreator { cliqueContext .getVoteProposer() .getVote(Util.publicKeyToAddress(nodeKeys.getPublicKey()), voteTally); - votingInterface.insertVoteToHeaderBuilder(builder, vote); + final BlockHeaderBuilder builderIncludingProposedVotes = + CliqueVotingBlockInterface.insertVoteToHeaderBuilder(builder, vote); - final CliqueExtraData sealedExtraData = constructSignedExtraData(builder.buildBlockHeader()); + final CliqueExtraData sealedExtraData = + constructSignedExtraData(builderIncludingProposedVotes.buildBlockHeader()); // Replace the extraData in the BlockHeaderBuilder, and return header. return builder.extraData(sealedExtraData.encode()).buildBlockHeader(); diff --git a/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueMinerExecutor.java b/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueMinerExecutor.java index 643baa9eb9..6d0e683143 100644 --- a/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueMinerExecutor.java +++ b/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueMinerExecutor.java @@ -14,6 +14,7 @@ package tech.pegasys.pantheon.consensus.clique.blockcreation; import tech.pegasys.pantheon.consensus.clique.CliqueContext; import tech.pegasys.pantheon.consensus.clique.CliqueExtraData; +import tech.pegasys.pantheon.consensus.common.ConsensusHelpers; import tech.pegasys.pantheon.consensus.common.EpochManager; import tech.pegasys.pantheon.consensus.common.VoteTally; import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair; @@ -29,7 +30,6 @@ import tech.pegasys.pantheon.ethereum.core.Util; import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule; import tech.pegasys.pantheon.util.Subscribers; import tech.pegasys.pantheon.util.bytes.BytesValue; -import tech.pegasys.pantheon.util.bytes.BytesValues; import java.util.List; import java.util.concurrent.ExecutorService; @@ -96,7 +96,8 @@ public class CliqueMinerExecutor extends AbstractMinerExecutor validators = Lists.newArrayList(); - final BytesValue vanityDataToInsert = createCorrectlySizedVanityData(); + final BytesValue vanityDataToInsert = + ConsensusHelpers.zeroLeftPad(vanityData, CliqueExtraData.EXTRA_VANITY_LENGTH); // Building ON TOP of canonical head, if the next block is epoch, include validators. if (epochManager.isEpochBlock(parentHeader.getNumber() + 1)) { final VoteTally voteTally = @@ -108,10 +109,4 @@ public class CliqueMinerExecutor extends AbstractMinerExecutor extractVoteFromHeader(final BlockHeader header); - BlockHeaderBuilder insertVoteToHeaderBuilder( - final BlockHeaderBuilder builder, final Optional vote); - List
validatorsInBlock(final BlockHeader header); } diff --git a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/IbftStateMachine.java b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/IbftStateMachine.java index 6d606452ce..d1960b9645 100644 --- a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/IbftStateMachine.java +++ b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/IbftStateMachine.java @@ -12,9 +12,17 @@ */ package tech.pegasys.pantheon.consensus.ibft; +import tech.pegasys.pantheon.consensus.ibft.blockcreation.IbftBlockCreatorFactory; + /** Stateful evaluator for ibft events */ public class IbftStateMachine { + private final IbftBlockCreatorFactory blockCreatorFactory; + + public IbftStateMachine(final IbftBlockCreatorFactory blockCreatorFactory) { + this.blockCreatorFactory = blockCreatorFactory; + } + /** * Attempt to consume the event and update the maintained state * diff --git a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/IbftVotingBlockInterface.java b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/IbftVotingBlockInterface.java index c69d9f0969..048b9aec85 100644 --- a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/IbftVotingBlockInterface.java +++ b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/IbftVotingBlockInterface.java @@ -17,7 +17,6 @@ import tech.pegasys.pantheon.consensus.common.VoteBlockInterface; import tech.pegasys.pantheon.consensus.common.VoteType; import tech.pegasys.pantheon.ethereum.core.Address; import tech.pegasys.pantheon.ethereum.core.BlockHeader; -import tech.pegasys.pantheon.ethereum.core.BlockHeaderBuilder; import java.util.List; import java.util.Optional; @@ -40,29 +39,6 @@ public class IbftVotingBlockInterface implements VoteBlockInterface { return Optional.empty(); } - @Override - public BlockHeaderBuilder insertVoteToHeaderBuilder( - final BlockHeaderBuilder builder, final Optional vote) { - final BlockHeader header = builder.buildBlockHeader(); - final IbftExtraData extraData = IbftExtraData.decode(header.getExtraData()); - - Optional headerVote = Optional.empty(); - - if (vote.isPresent()) { - final ValidatorVote voteToCast = vote.get(); - headerVote = Optional.of(new Vote(voteToCast.getRecipient(), voteToCast.getVotePolarity())); - } - - final IbftExtraData includingVote = - new IbftExtraData( - extraData.getVanityData(), - extraData.getSeals(), - headerVote, - extraData.getRound(), - extraData.getValidators()); - return BlockHeaderBuilder.fromHeader(header).extraData(includingVote.encode()); - } - @Override public List
validatorsInBlock(final BlockHeader header) { final IbftExtraData ibftExtraData = IbftExtraData.decode(header.getExtraData()); diff --git a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/blockcreation/IbftBlockCreator.java b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/blockcreation/IbftBlockCreator.java index b9aefff145..de0fe34829 100644 --- a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/blockcreation/IbftBlockCreator.java +++ b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/blockcreation/IbftBlockCreator.java @@ -16,40 +16,55 @@ import tech.pegasys.pantheon.consensus.ibft.IbftContext; 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.BlockHashFunction; import tech.pegasys.pantheon.ethereum.core.BlockHeader; +import tech.pegasys.pantheon.ethereum.core.BlockHeaderBuilder; +import tech.pegasys.pantheon.ethereum.core.Hash; 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.ProtocolSchedule; +import tech.pegasys.pantheon.ethereum.mainnet.ScheduleBasedBlockHashFunction; import java.util.function.Function; -// TODO: Just a placeholder. Implementation is required. +// This class is responsible for creating a block without committer seals (basically it was just +// too hard to coordinate with the state machine). public class IbftBlockCreator extends AbstractBlockCreator { public IbftBlockCreator( - final Address coinbase, + final Address localAddress, final ExtraDataCalculator extraDataCalculator, final PendingTransactions pendingTransactions, final ProtocolContext protocolContext, final ProtocolSchedule protocolSchedule, final Function gasLimitCalculator, final Wei minTransactionGasPrice, - final Address miningBeneficiary, final BlockHeader parentHeader) { super( - coinbase, + localAddress, extraDataCalculator, pendingTransactions, protocolContext, protocolSchedule, gasLimitCalculator, minTransactionGasPrice, - miningBeneficiary, + localAddress, parentHeader); } @Override protected BlockHeader createFinalBlockHeader(final SealableBlockHeader sealableBlockHeader) { - return null; + + final BlockHashFunction blockHashFunction = + ScheduleBasedBlockHashFunction.create(protocolSchedule); + + final BlockHeaderBuilder builder = + BlockHeaderBuilder.create() + .populateFrom(sealableBlockHeader) + .mixHash(Hash.ZERO) + .nonce(0L) + .blockHashFunction(blockHashFunction); + + return builder.buildBlockHeader(); } } diff --git a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/blockcreation/IbftBlockCreatorFactory.java b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/blockcreation/IbftBlockCreatorFactory.java new file mode 100644 index 0000000000..60a3d34130 --- /dev/null +++ b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/blockcreation/IbftBlockCreatorFactory.java @@ -0,0 +1,110 @@ +/* + * 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 tech.pegasys.pantheon.consensus.ibft.blockcreation; + +import tech.pegasys.pantheon.consensus.common.ConsensusHelpers; +import tech.pegasys.pantheon.consensus.common.ValidatorVote; +import tech.pegasys.pantheon.consensus.common.VoteTally; +import tech.pegasys.pantheon.consensus.ibft.IbftContext; +import tech.pegasys.pantheon.consensus.ibft.IbftExtraData; +import tech.pegasys.pantheon.consensus.ibft.Vote; +import tech.pegasys.pantheon.ethereum.ProtocolContext; +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.Wei; +import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule; +import tech.pegasys.pantheon.util.bytes.BytesValue; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; + +public class IbftBlockCreatorFactory { + + private final Function gasLimitCalculator; + private final PendingTransactions pendingTransactions; + protected final ProtocolContext protocolContext; + protected final ProtocolSchedule protocolSchedule; + private final Address localAddress; + + private volatile BytesValue vanityData; + private volatile Wei minTransactionGasPrice; + + public IbftBlockCreatorFactory( + final Function gasLimitCalculator, + final PendingTransactions pendingTransactions, + final ProtocolContext protocolContext, + final ProtocolSchedule protocolSchedule, + final MiningParameters miningParams, + final Address localAddress) { + this.gasLimitCalculator = gasLimitCalculator; + this.pendingTransactions = pendingTransactions; + this.protocolContext = protocolContext; + this.protocolSchedule = protocolSchedule; + this.localAddress = localAddress; + this.minTransactionGasPrice = miningParams.getMinTransactionGasPrice(); + this.vanityData = miningParams.getExtraData(); + } + + public IbftBlockCreator create(final BlockHeader parentHeader, final int round) { + return new IbftBlockCreator( + localAddress, + ph -> createExtraData(round), + pendingTransactions, + protocolContext, + protocolSchedule, + gasLimitCalculator, + minTransactionGasPrice, + parentHeader); + } + + public void setExtraData(final BytesValue extraData) { + this.vanityData = extraData.copy(); + } + + public void setMinTransactionGasPrice(final Wei minTransactionGasPrice) { + this.minTransactionGasPrice = minTransactionGasPrice.copy(); + } + + public Wei getMinTransactionGasPrice() { + return minTransactionGasPrice; + } + + public BytesValue createExtraData(final int round) { + final VoteTally voteTally = protocolContext.getConsensusState().getVoteTally(); + final Optional proposal = + protocolContext.getConsensusState().getVoteProposer().getVote(localAddress, voteTally); + + final List
validators = new ArrayList<>(voteTally.getCurrentValidators()); + + final IbftExtraData extraData = + new IbftExtraData( + ConsensusHelpers.zeroLeftPad(vanityData, IbftExtraData.EXTRA_VANITY_LENGTH), + Collections.emptyList(), + toVote(proposal), + round, + validators); + + return extraData.encode(); + } + + private static Optional toVote(final Optional input) { + return input + .map(v -> Optional.of(new Vote(v.getRecipient(), v.getVotePolarity()))) + .orElse(Optional.empty()); + } +} diff --git a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/blockcreation/IbftMiningCoordinator.java b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/blockcreation/IbftMiningCoordinator.java new file mode 100644 index 0000000000..e61fd7f716 --- /dev/null +++ b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/blockcreation/IbftMiningCoordinator.java @@ -0,0 +1,50 @@ +/* + * 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 tech.pegasys.pantheon.consensus.ibft.blockcreation; + +import tech.pegasys.pantheon.ethereum.blockcreation.MiningCoordinator; +import tech.pegasys.pantheon.ethereum.core.Wei; +import tech.pegasys.pantheon.util.bytes.BytesValue; + +public class IbftMiningCoordinator implements MiningCoordinator { + + private final IbftBlockCreatorFactory blockCreatorFactory; + + public IbftMiningCoordinator(final IbftBlockCreatorFactory blockCreatorFactory) { + this.blockCreatorFactory = blockCreatorFactory; + } + + @Override + public void enable() {} + + @Override + public void disable() {} + + @Override + public boolean isRunning() { + return true; + } + + @Override + public void setMinTransactionGasPrice(final Wei minGasPrice) {} + + @Override + public Wei getMinTransactionGasPrice() { + return null; + } + + @Override + public void setExtraData(final BytesValue extraData) { + blockCreatorFactory.setExtraData(extraData); + } +} diff --git a/consensus/ibftlegacy/src/main/java/tech/pegasys/pantheon/consensus/ibftlegacy/IbftLegacyVotingBlockInterface.java b/consensus/ibftlegacy/src/main/java/tech/pegasys/pantheon/consensus/ibftlegacy/IbftLegacyVotingBlockInterface.java index cac3b2b425..8a94009b9e 100644 --- a/consensus/ibftlegacy/src/main/java/tech/pegasys/pantheon/consensus/ibftlegacy/IbftLegacyVotingBlockInterface.java +++ b/consensus/ibftlegacy/src/main/java/tech/pegasys/pantheon/consensus/ibftlegacy/IbftLegacyVotingBlockInterface.java @@ -52,8 +52,7 @@ public class IbftLegacyVotingBlockInterface implements VoteBlockInterface { return Optional.empty(); } - @Override - public BlockHeaderBuilder insertVoteToHeaderBuilder( + public static BlockHeaderBuilder insertVoteToHeaderBuilder( final BlockHeaderBuilder builder, final Optional vote) { if (vote.isPresent()) { final ValidatorVote voteToCast = vote.get(); diff --git a/consensus/ibftlegacy/src/test/java/tech/pegasys/pantheon/consensus/ibftlegacy/IbftLegacyVotingBlockInterfaceTest.java b/consensus/ibftlegacy/src/test/java/tech/pegasys/pantheon/consensus/ibftlegacy/IbftLegacyVotingBlockInterfaceTest.java index c78781b2e5..2405161af3 100644 --- a/consensus/ibftlegacy/src/test/java/tech/pegasys/pantheon/consensus/ibftlegacy/IbftLegacyVotingBlockInterfaceTest.java +++ b/consensus/ibftlegacy/src/test/java/tech/pegasys/pantheon/consensus/ibftlegacy/IbftLegacyVotingBlockInterfaceTest.java @@ -86,7 +86,7 @@ public class IbftLegacyVotingBlockInterfaceTest { final ValidatorVote vote = new ValidatorVote(ADD, AddressHelpers.ofValue(1), AddressHelpers.ofValue(2)); final BlockHeaderBuilder builderWithVote = - blockInterface.insertVoteToHeaderBuilder(builder, Optional.of(vote)); + IbftLegacyVotingBlockInterface.insertVoteToHeaderBuilder(builder, Optional.of(vote)); final BlockHeader header = builderWithVote.buildBlockHeader(); @@ -99,7 +99,7 @@ public class IbftLegacyVotingBlockInterfaceTest { final ValidatorVote vote = new ValidatorVote(DROP, AddressHelpers.ofValue(1), AddressHelpers.ofValue(2)); final BlockHeaderBuilder builderWithVote = - blockInterface.insertVoteToHeaderBuilder(builder, Optional.of(vote)); + IbftLegacyVotingBlockInterface.insertVoteToHeaderBuilder(builder, Optional.of(vote)); final BlockHeader header = builderWithVote.buildBlockHeader(); @@ -110,7 +110,7 @@ public class IbftLegacyVotingBlockInterfaceTest { @Test public void nonVoteBlendedIntoHeaderResultsInACoinbaseOfZero() { final BlockHeaderBuilder builderWithVote = - blockInterface.insertVoteToHeaderBuilder(builder, Optional.empty()); + IbftLegacyVotingBlockInterface.insertVoteToHeaderBuilder(builder, Optional.empty()); final BlockHeader header = builderWithVote.buildBlockHeader(); @@ -123,8 +123,7 @@ public class IbftLegacyVotingBlockInterfaceTest { final BlockHeader header = TestHelpers.createIbftSignedBlockHeader(headerBuilder, proposerKeys, validatorList); - final IbftLegacyVotingBlockInterface serDeser = new IbftLegacyVotingBlockInterface(); - final List
extractedValidators = serDeser.validatorsInBlock(header); + final List
extractedValidators = blockInterface.validatorsInBlock(header); assertThat(extractedValidators).isEqualTo(validatorList); } diff --git a/ethereum/blockcreation/src/main/java/tech/pegasys/pantheon/ethereum/blockcreation/AbstractMiningCoordinator.java b/ethereum/blockcreation/src/main/java/tech/pegasys/pantheon/ethereum/blockcreation/AbstractMiningCoordinator.java index b0eb03cdc1..810d907f4f 100644 --- a/ethereum/blockcreation/src/main/java/tech/pegasys/pantheon/ethereum/blockcreation/AbstractMiningCoordinator.java +++ b/ethereum/blockcreation/src/main/java/tech/pegasys/pantheon/ethereum/blockcreation/AbstractMiningCoordinator.java @@ -18,12 +18,9 @@ import tech.pegasys.pantheon.ethereum.chain.BlockAddedEvent; 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.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; @@ -138,34 +135,4 @@ public abstract class AbstractMiningCoordinator< public void setExtraData(final BytesValue extraData) { executor.setExtraData(extraData); } - - @Override - public void setCoinbase(final Address coinbase) { - throw new UnsupportedOperationException( - "Current consensus mechanism prevents setting coinbase."); - } - - @Override - public Optional
getCoinbase() { - throw new UnsupportedOperationException( - "Current consensus mechanism prevents querying of coinbase."); - } - - @Override - public Optional hashesPerSecond() { - throw new UnsupportedOperationException( - "Current consensus mechanism prevents querying of hashrate."); - } - - @Override - public Optional getWorkDefinition() { - throw new UnsupportedOperationException( - "Current consensus mechanism prevents querying work definition."); - } - - @Override - public boolean submitWork(final EthHashSolution solution) { - throw new UnsupportedOperationException( - "Current consensus mechanism prevents submission of work solutions."); - } } diff --git a/ethereum/blockcreation/src/main/java/tech/pegasys/pantheon/ethereum/blockcreation/MiningCoordinator.java b/ethereum/blockcreation/src/main/java/tech/pegasys/pantheon/ethereum/blockcreation/MiningCoordinator.java index 8c88e4307c..f6bffdaff8 100644 --- a/ethereum/blockcreation/src/main/java/tech/pegasys/pantheon/ethereum/blockcreation/MiningCoordinator.java +++ b/ethereum/blockcreation/src/main/java/tech/pegasys/pantheon/ethereum/blockcreation/MiningCoordinator.java @@ -35,13 +35,28 @@ public interface MiningCoordinator { void setExtraData(BytesValue extraData); - void setCoinbase(Address coinbase); - - Optional
getCoinbase(); - - Optional hashesPerSecond(); - - Optional getWorkDefinition(); - - boolean submitWork(EthHashSolution solution); + default void setCoinbase(final Address coinbase) { + throw new UnsupportedOperationException( + "Current consensus mechanism prevents setting coinbase."); + } + + default Optional
getCoinbase() { + throw new UnsupportedOperationException( + "Current consensus mechanism prevents querying of coinbase."); + } + + default Optional hashesPerSecond() { + throw new UnsupportedOperationException( + "Current consensus mechanism prevents querying of hashrate."); + } + + default Optional getWorkDefinition() { + throw new UnsupportedOperationException( + "Current consensus mechanism prevents querying work definition."); + } + + default boolean submitWork(final EthHashSolution solution) { + throw new UnsupportedOperationException( + "Current consensus mechanism prevents submission of work solutions."); + } } diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/controller/IbftPantheonController.java b/pantheon/src/main/java/tech/pegasys/pantheon/controller/IbftPantheonController.java index 07000bac4b..9f0a5a4536 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/controller/IbftPantheonController.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/controller/IbftPantheonController.java @@ -25,6 +25,8 @@ import tech.pegasys.pantheon.consensus.ibft.IbftContext; import tech.pegasys.pantheon.consensus.ibft.IbftEventQueue; import tech.pegasys.pantheon.consensus.ibft.IbftProcessor; import tech.pegasys.pantheon.consensus.ibft.IbftStateMachine; +import tech.pegasys.pantheon.consensus.ibft.blockcreation.IbftBlockCreatorFactory; +import tech.pegasys.pantheon.consensus.ibft.blockcreation.IbftMiningCoordinator; import tech.pegasys.pantheon.consensus.ibft.network.IbftNetworkPeers; import tech.pegasys.pantheon.consensus.ibft.protocol.IbftProtocolManager; import tech.pegasys.pantheon.consensus.ibft.protocol.IbftSubProtocol; @@ -38,8 +40,10 @@ import tech.pegasys.pantheon.ethereum.blockcreation.MiningCoordinator; import tech.pegasys.pantheon.ethereum.chain.GenesisState; import tech.pegasys.pantheon.ethereum.chain.MutableBlockchain; import tech.pegasys.pantheon.ethereum.core.Hash; +import tech.pegasys.pantheon.ethereum.core.MiningParameters; import tech.pegasys.pantheon.ethereum.core.Synchronizer; import tech.pegasys.pantheon.ethereum.core.TransactionPool; +import tech.pegasys.pantheon.ethereum.core.Util; import tech.pegasys.pantheon.ethereum.db.BlockchainStorage; import tech.pegasys.pantheon.ethereum.db.DefaultMutableBlockchain; import tech.pegasys.pantheon.ethereum.db.WorldStateArchive; @@ -106,6 +110,7 @@ public class IbftPantheonController implements PantheonController { final StorageProvider storageProvider, final GenesisConfigFile genesisConfig, final SynchronizerConfiguration taintedSyncConfig, + final MiningParameters miningParams, final boolean ottomanTestnetOperation, final int networkId, final KeyPair nodeKeys) { @@ -167,19 +172,35 @@ public class IbftPantheonController implements PantheonController { ethProtocolManager.ethContext(), syncState); + final TransactionPool transactionPool = + TransactionPoolFactory.createTransactionPool( + protocolSchedule, protocolContext, ethProtocolManager.ethContext()); + final IbftEventQueue ibftEventQueue = new IbftEventQueue(); blockchain.observeBlockAdded(new IbftChainObserver(ibftEventQueue)); - final IbftStateMachine ibftStateMachine = new IbftStateMachine(); + final IbftBlockCreatorFactory blockCreatorFactory = + new IbftBlockCreatorFactory( + (gasLimit) -> gasLimit, + transactionPool.getPendingTransactions(), + protocolContext, + protocolSchedule, + miningParams, + Util.publicKeyToAddress(nodeKeys.getPublicKey())); + + final IbftStateMachine ibftStateMachine = new IbftStateMachine(blockCreatorFactory); final IbftProcessor ibftProcessor = new IbftProcessor(ibftEventQueue, ibftConfig.getRequestTimeoutMillis(), ibftStateMachine); final ExecutorService processorExecutor = Executors.newSingleThreadExecutor(); processorExecutor.submit(ibftProcessor); + final MiningCoordinator ibftMiningCoordinator = new IbftMiningCoordinator(blockCreatorFactory); + final Runnable closer = () -> { ibftProcessor.stop(); + ibftMiningCoordinator.disable(); processorExecutor.shutdownNow(); try { processorExecutor.awaitTermination(5, TimeUnit.SECONDS); @@ -193,10 +214,6 @@ public class IbftPantheonController implements PantheonController { } }; - final TransactionPool transactionPool = - TransactionPoolFactory.createTransactionPool( - protocolSchedule, protocolContext, ethProtocolManager.ethContext()); - final IbftNetworkPeers peers = new IbftNetworkPeers(protocolContext.getConsensusState().getVoteTally()); diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/controller/PantheonController.java b/pantheon/src/main/java/tech/pegasys/pantheon/controller/PantheonController.java index 3cbc739121..ea2faa3c67 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/controller/PantheonController.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/controller/PantheonController.java @@ -56,6 +56,7 @@ public interface PantheonController extends Closeable { storageProvider, genesisConfigFile, syncConfig, + miningParameters, ottomanTestnetOperation, networkId, nodeKeys);