mirror of https://github.com/hyperledger/besu
Common protocol schedule config handling (#250)
* Introduce ProtocolScheduleBuilder and use it for Clique, MainNet, IBFT and dev. * Remove default milestone blocks and simplify MainnetProtocolSchedule. All milestone blocks must now be defined in the genesis file (previously ethash chains would get Mainnet milestone blocks by default). Signed-off-by: Adrian Sutton <adrian.sutton@consensys.net>pull/2/head
parent
e899ba98b1
commit
fd81e97ad9
@ -0,0 +1,102 @@ |
||||
/* |
||||
* 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.config; |
||||
|
||||
import java.util.OptionalInt; |
||||
import java.util.OptionalLong; |
||||
|
||||
import io.vertx.core.json.JsonObject; |
||||
|
||||
public class JsonGenesisConfigOptions implements GenesisConfigOptions { |
||||
|
||||
private static final String ETHASH_CONFIG_KEY = "ethash"; |
||||
private static final String IBFT_CONFIG_KEY = "ibft"; |
||||
private static final String CLIQUE_CONFIG_KEY = "clique"; |
||||
private final JsonObject configRoot; |
||||
|
||||
JsonGenesisConfigOptions(final JsonObject configRoot) { |
||||
this.configRoot = configRoot != null ? configRoot : new JsonObject(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isEthHash() { |
||||
return configRoot.containsKey(ETHASH_CONFIG_KEY); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isIbft() { |
||||
return configRoot.containsKey(IBFT_CONFIG_KEY); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isClique() { |
||||
return configRoot.containsKey(CLIQUE_CONFIG_KEY); |
||||
} |
||||
|
||||
@Override |
||||
public IbftConfigOptions getIbftConfigOptions() { |
||||
return isIbft() |
||||
? new IbftConfigOptions(configRoot.getJsonObject(IBFT_CONFIG_KEY)) |
||||
: IbftConfigOptions.DEFAULT; |
||||
} |
||||
|
||||
@Override |
||||
public CliqueConfigOptions getCliqueConfigOptions() { |
||||
return isClique() |
||||
? new CliqueConfigOptions(configRoot.getJsonObject(CLIQUE_CONFIG_KEY)) |
||||
: CliqueConfigOptions.DEFAULT; |
||||
} |
||||
|
||||
@Override |
||||
public OptionalLong getHomesteadBlockNumber() { |
||||
return getOptionalLong("homesteadblock"); |
||||
} |
||||
|
||||
@Override |
||||
public OptionalLong getDaoForkBlock() { |
||||
return getOptionalLong("daoforkblock"); |
||||
} |
||||
|
||||
@Override |
||||
public OptionalLong getTangerineWhistleBlockNumber() { |
||||
return getOptionalLong("eip150block"); |
||||
} |
||||
|
||||
@Override |
||||
public OptionalLong getSpuriousDragonBlockNumber() { |
||||
return getOptionalLong("eip158block"); |
||||
} |
||||
|
||||
@Override |
||||
public OptionalLong getByzantiumBlockNumber() { |
||||
return getOptionalLong("byzantiumblock"); |
||||
} |
||||
|
||||
@Override |
||||
public OptionalLong getConstantinopleBlockNumber() { |
||||
return getOptionalLong("constantinopleblock"); |
||||
} |
||||
|
||||
@Override |
||||
public OptionalInt getChainId() { |
||||
return configRoot.containsKey("chainid") |
||||
? OptionalInt.of(configRoot.getInteger("chainid")) |
||||
: OptionalInt.empty(); |
||||
} |
||||
|
||||
private OptionalLong getOptionalLong(final String key) { |
||||
return configRoot.containsKey(key) |
||||
? OptionalLong.of(configRoot.getLong(key)) |
||||
: OptionalLong.empty(); |
||||
} |
||||
} |
@ -0,0 +1,122 @@ |
||||
/* |
||||
* 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.config; |
||||
|
||||
import java.util.OptionalInt; |
||||
import java.util.OptionalLong; |
||||
|
||||
public class StubGenesisConfigOptions implements GenesisConfigOptions { |
||||
|
||||
private OptionalLong homesteadBlockNumber = OptionalLong.empty(); |
||||
private OptionalLong daoForkBlock = OptionalLong.empty(); |
||||
private OptionalLong tangerineWhistleBlockNumber = OptionalLong.empty(); |
||||
private OptionalLong spuriousDragonBlockNumber = OptionalLong.empty(); |
||||
private OptionalLong byzantiumBlockNumber = OptionalLong.empty(); |
||||
private OptionalLong constantinopleBlockNumber = OptionalLong.empty(); |
||||
private OptionalInt chainId = OptionalInt.empty(); |
||||
|
||||
@Override |
||||
public boolean isEthHash() { |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public boolean isIbft() { |
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
public boolean isClique() { |
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
public IbftConfigOptions getIbftConfigOptions() { |
||||
return IbftConfigOptions.DEFAULT; |
||||
} |
||||
|
||||
@Override |
||||
public CliqueConfigOptions getCliqueConfigOptions() { |
||||
return CliqueConfigOptions.DEFAULT; |
||||
} |
||||
|
||||
@Override |
||||
public OptionalLong getHomesteadBlockNumber() { |
||||
return homesteadBlockNumber; |
||||
} |
||||
|
||||
@Override |
||||
public OptionalLong getDaoForkBlock() { |
||||
return daoForkBlock; |
||||
} |
||||
|
||||
@Override |
||||
public OptionalLong getTangerineWhistleBlockNumber() { |
||||
return tangerineWhistleBlockNumber; |
||||
} |
||||
|
||||
@Override |
||||
public OptionalLong getSpuriousDragonBlockNumber() { |
||||
return spuriousDragonBlockNumber; |
||||
} |
||||
|
||||
@Override |
||||
public OptionalLong getByzantiumBlockNumber() { |
||||
return byzantiumBlockNumber; |
||||
} |
||||
|
||||
@Override |
||||
public OptionalLong getConstantinopleBlockNumber() { |
||||
return constantinopleBlockNumber; |
||||
} |
||||
|
||||
@Override |
||||
public OptionalInt getChainId() { |
||||
return chainId; |
||||
} |
||||
|
||||
public StubGenesisConfigOptions homesteadBlock(final long blockNumber) { |
||||
homesteadBlockNumber = OptionalLong.of(blockNumber); |
||||
return this; |
||||
} |
||||
|
||||
public StubGenesisConfigOptions daoForkBlock(final long blockNumber) { |
||||
daoForkBlock = OptionalLong.of(blockNumber); |
||||
return this; |
||||
} |
||||
|
||||
public StubGenesisConfigOptions eip150Block(final long blockNumber) { |
||||
tangerineWhistleBlockNumber = OptionalLong.of(blockNumber); |
||||
return this; |
||||
} |
||||
|
||||
public StubGenesisConfigOptions eip158Block(final long blockNumber) { |
||||
spuriousDragonBlockNumber = OptionalLong.of(blockNumber); |
||||
return this; |
||||
} |
||||
|
||||
public StubGenesisConfigOptions byzantiumBlock(final long blockNumber) { |
||||
byzantiumBlockNumber = OptionalLong.of(blockNumber); |
||||
return this; |
||||
} |
||||
|
||||
public StubGenesisConfigOptions constantinopleBlock(final long blockNumber) { |
||||
constantinopleBlockNumber = OptionalLong.of(blockNumber); |
||||
return this; |
||||
} |
||||
|
||||
public StubGenesisConfigOptions chainId(final int chainId) { |
||||
this.chainId = OptionalInt.of(chainId); |
||||
return this; |
||||
} |
||||
} |
@ -1,87 +0,0 @@ |
||||
/* |
||||
* 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.clique; |
||||
|
||||
import static tech.pegasys.pantheon.consensus.clique.BlockHeaderValidationRulesetFactory.cliqueBlockHeaderValidator; |
||||
|
||||
import tech.pegasys.pantheon.consensus.common.EpochManager; |
||||
import tech.pegasys.pantheon.ethereum.core.Address; |
||||
import tech.pegasys.pantheon.ethereum.core.Wei; |
||||
import tech.pegasys.pantheon.ethereum.mainnet.MainnetBlockBodyValidator; |
||||
import tech.pegasys.pantheon.ethereum.mainnet.MainnetBlockImporter; |
||||
import tech.pegasys.pantheon.ethereum.mainnet.MainnetProtocolSpecs; |
||||
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule; |
||||
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSpec; |
||||
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSpecBuilder; |
||||
|
||||
/** Factory for producing Clique protocol specs for given configurations and known fork points */ |
||||
public class CliqueProtocolSpecs { |
||||
|
||||
private final long secondsBetweenBlocks; |
||||
private final long epochLength; |
||||
private final Address localNodeAddress; |
||||
private final ProtocolSchedule<CliqueContext> protocolSchedule; |
||||
|
||||
public CliqueProtocolSpecs( |
||||
final long secondsBetweenBlocks, |
||||
final long epochLength, |
||||
final Address localNodeAddress, |
||||
final ProtocolSchedule<CliqueContext> protocolSchedule) { |
||||
this.secondsBetweenBlocks = secondsBetweenBlocks; |
||||
this.epochLength = epochLength; |
||||
this.localNodeAddress = localNodeAddress; |
||||
this.protocolSchedule = protocolSchedule; |
||||
} |
||||
|
||||
public ProtocolSpec<CliqueContext> frontier() { |
||||
return applyCliqueSpecificModifications(MainnetProtocolSpecs.frontierDefinition()); |
||||
} |
||||
|
||||
public ProtocolSpec<CliqueContext> homestead() { |
||||
return applyCliqueSpecificModifications(MainnetProtocolSpecs.homesteadDefinition()); |
||||
} |
||||
|
||||
public ProtocolSpec<CliqueContext> tangerineWhistle() { |
||||
return applyCliqueSpecificModifications(MainnetProtocolSpecs.tangerineWhistleDefinition()); |
||||
} |
||||
|
||||
public ProtocolSpec<CliqueContext> spuriousDragon() { |
||||
return applyCliqueSpecificModifications( |
||||
MainnetProtocolSpecs.spuriousDragonDefinition(protocolSchedule.getChainId())); |
||||
} |
||||
|
||||
public ProtocolSpec<CliqueContext> byzantium() { |
||||
return applyCliqueSpecificModifications( |
||||
MainnetProtocolSpecs.byzantiumDefinition(protocolSchedule.getChainId())); |
||||
} |
||||
|
||||
public ProtocolSpec<CliqueContext> constantinople() { |
||||
return applyCliqueSpecificModifications( |
||||
MainnetProtocolSpecs.constantinopleDefinition(protocolSchedule.getChainId())); |
||||
} |
||||
|
||||
private ProtocolSpec<CliqueContext> applyCliqueSpecificModifications( |
||||
final ProtocolSpecBuilder<Void> specBuilder) { |
||||
final EpochManager epochManager = new EpochManager(epochLength); |
||||
return specBuilder |
||||
.<CliqueContext>changeConsensusContextType( |
||||
difficultyCalculator -> cliqueBlockHeaderValidator(secondsBetweenBlocks, epochManager), |
||||
difficultyCalculator -> cliqueBlockHeaderValidator(secondsBetweenBlocks, epochManager), |
||||
MainnetBlockBodyValidator::new, |
||||
MainnetBlockImporter::new, |
||||
new CliqueDifficultyCalculator(localNodeAddress)) |
||||
.blockReward(Wei.ZERO) |
||||
.miningBeneficiaryCalculator(CliqueHelpers::getProposerOfBlock) |
||||
.build(protocolSchedule); |
||||
} |
||||
} |
@ -1,57 +0,0 @@ |
||||
/* |
||||
* 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.clique; |
||||
|
||||
import static org.assertj.core.api.Java6Assertions.assertThat; |
||||
|
||||
import tech.pegasys.pantheon.ethereum.core.AddressHelpers; |
||||
import tech.pegasys.pantheon.ethereum.core.Wei; |
||||
import tech.pegasys.pantheon.ethereum.mainnet.MainnetProtocolSpecs; |
||||
import tech.pegasys.pantheon.ethereum.mainnet.MutableProtocolSchedule; |
||||
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule; |
||||
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSpec; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
public class CliqueProtocolSpecsTest { |
||||
|
||||
private static final int CHAIN_ID = 5; |
||||
CliqueProtocolSpecs protocolSpecs = |
||||
new CliqueProtocolSpecs( |
||||
15, 30_000, AddressHelpers.ofValue(5), new MutableProtocolSchedule<>(CHAIN_ID)); |
||||
|
||||
@Test |
||||
public void homsteadParametersAlignWithMainnetWithAdjustments() { |
||||
final ProtocolSpec<CliqueContext> homestead = protocolSpecs.homestead(); |
||||
|
||||
assertThat(homestead.getName()).isEqualTo("Homestead"); |
||||
assertThat(homestead.getBlockReward()).isEqualTo(Wei.ZERO); |
||||
assertThat(homestead.getDifficultyCalculator()).isInstanceOf(CliqueDifficultyCalculator.class); |
||||
} |
||||
|
||||
@Test |
||||
public void allSpecsInheritFromMainnetCounterparts() { |
||||
final ProtocolSchedule<Void> mainnetProtocolSchedule = new MutableProtocolSchedule<>(CHAIN_ID); |
||||
|
||||
assertThat(protocolSpecs.frontier().getName()) |
||||
.isEqualTo(MainnetProtocolSpecs.frontier(mainnetProtocolSchedule).getName()); |
||||
assertThat(protocolSpecs.homestead().getName()) |
||||
.isEqualTo(MainnetProtocolSpecs.homestead(mainnetProtocolSchedule).getName()); |
||||
assertThat(protocolSpecs.tangerineWhistle().getName()) |
||||
.isEqualTo(MainnetProtocolSpecs.tangerineWhistle(mainnetProtocolSchedule).getName()); |
||||
assertThat(protocolSpecs.spuriousDragon().getName()) |
||||
.isEqualTo(MainnetProtocolSpecs.spuriousDragon(1, mainnetProtocolSchedule).getName()); |
||||
assertThat(protocolSpecs.byzantium().getName()) |
||||
.isEqualTo(MainnetProtocolSpecs.byzantium(1, mainnetProtocolSchedule).getName()); |
||||
} |
||||
} |
@ -1,63 +0,0 @@ |
||||
/* |
||||
* 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.ibftlegacy; |
||||
|
||||
import static tech.pegasys.pantheon.consensus.ibftlegacy.IbftBlockHeaderValidationRulesetFactory.ibftBlockHeaderValidator; |
||||
|
||||
import tech.pegasys.pantheon.consensus.common.EpochManager; |
||||
import tech.pegasys.pantheon.consensus.ibft.IbftBlockImporter; |
||||
import tech.pegasys.pantheon.consensus.ibft.IbftContext; |
||||
import tech.pegasys.pantheon.ethereum.core.Wei; |
||||
import tech.pegasys.pantheon.ethereum.mainnet.MainnetBlockBodyValidator; |
||||
import tech.pegasys.pantheon.ethereum.mainnet.MainnetBlockImporter; |
||||
import tech.pegasys.pantheon.ethereum.mainnet.MainnetProtocolSpecs; |
||||
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule; |
||||
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSpec; |
||||
|
||||
import java.math.BigInteger; |
||||
|
||||
/** Factory for producing Ibft protocol specs for given configurations and known fork points */ |
||||
public class IbftProtocolSpecs { |
||||
|
||||
/** |
||||
* Produce the ProtocolSpec for an IBFT chain that uses spurious dragon milestone configuration |
||||
* |
||||
* @param secondsBetweenBlocks the block period in seconds |
||||
* @param epochLength the number of blocks in each epoch |
||||
* @param chainId the id of the Chain. |
||||
* @param protocolSchedule the {@link ProtocolSchedule} this spec will be part of |
||||
* @return a configured ProtocolSpec for dealing with IBFT blocks |
||||
*/ |
||||
public static ProtocolSpec<IbftContext> spuriousDragon( |
||||
final long secondsBetweenBlocks, |
||||
final long epochLength, |
||||
final int chainId, |
||||
final ProtocolSchedule<IbftContext> protocolSchedule) { |
||||
final EpochManager epochManager = new EpochManager(epochLength); |
||||
return MainnetProtocolSpecs.spuriousDragonDefinition(chainId) |
||||
.<IbftContext>changeConsensusContextType( |
||||
difficultyCalculator -> ibftBlockHeaderValidator(secondsBetweenBlocks), |
||||
difficultyCalculator -> ibftBlockHeaderValidator(secondsBetweenBlocks), |
||||
MainnetBlockBodyValidator::new, |
||||
(blockHeaderValidator, blockBodyValidator, blockProcessor) -> |
||||
new IbftBlockImporter( |
||||
new MainnetBlockImporter<>( |
||||
blockHeaderValidator, blockBodyValidator, blockProcessor), |
||||
new IbftVoteTallyUpdater(epochManager)), |
||||
(time, parent, protocolContext) -> BigInteger.ONE) |
||||
.blockReward(Wei.ZERO) |
||||
.blockHashFunction(IbftBlockHashing::calculateHashOfIbftBlockOnChain) |
||||
.name("IBFT") |
||||
.build(protocolSchedule); |
||||
} |
||||
} |
@ -1,36 +0,0 @@ |
||||
/* |
||||
* 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.ethereum.development; |
||||
|
||||
import tech.pegasys.pantheon.ethereum.mainnet.MainnetProtocolSpecs; |
||||
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule; |
||||
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSpec; |
||||
|
||||
/** |
||||
* Provides a protocol specification which is suitable for use on private, PoW networks, where block |
||||
* mining is performed on CPUs alone. |
||||
*/ |
||||
public class DevelopmentProtocolSpecs { |
||||
|
||||
/* |
||||
* The DevelopmentProtocolSpecification is the same as the byzantium spec, but with a much reduced |
||||
* difficulty calculator (to support CPU mining). |
||||
*/ |
||||
public static ProtocolSpec<Void> first( |
||||
final Integer chainId, final ProtocolSchedule<Void> protocolSchedule) { |
||||
return MainnetProtocolSpecs.byzantiumDefinition(chainId) |
||||
.difficultyCalculator(DevelopmentDifficultyCalculators.DEVELOPER) |
||||
.name("first") |
||||
.build(protocolSchedule); |
||||
} |
||||
} |
@ -0,0 +1,96 @@ |
||||
/* |
||||
* 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.ethereum.mainnet; |
||||
|
||||
import tech.pegasys.pantheon.config.GenesisConfigOptions; |
||||
|
||||
import java.util.OptionalLong; |
||||
import java.util.function.Function; |
||||
|
||||
public class ProtocolScheduleBuilder<C> { |
||||
|
||||
private final GenesisConfigOptions config; |
||||
private final Function<ProtocolSpecBuilder<Void>, ProtocolSpecBuilder<C>> protocolSpecAdapter; |
||||
private final int defaultChainId; |
||||
|
||||
public ProtocolScheduleBuilder( |
||||
final GenesisConfigOptions config, |
||||
final int defaultChainId, |
||||
final Function<ProtocolSpecBuilder<Void>, ProtocolSpecBuilder<C>> protocolSpecAdapter) { |
||||
this.config = config; |
||||
this.protocolSpecAdapter = protocolSpecAdapter; |
||||
this.defaultChainId = defaultChainId; |
||||
} |
||||
|
||||
public ProtocolSchedule<C> createProtocolSchedule() { |
||||
final int chainId = config.getChainId().orElse(defaultChainId); |
||||
final MutableProtocolSchedule<C> protocolSchedule = new MutableProtocolSchedule<>(chainId); |
||||
|
||||
addProtocolSpec( |
||||
protocolSchedule, OptionalLong.of(0), MainnetProtocolSpecs.frontierDefinition()); |
||||
addProtocolSpec( |
||||
protocolSchedule, |
||||
config.getHomesteadBlockNumber(), |
||||
MainnetProtocolSpecs.homesteadDefinition()); |
||||
|
||||
config |
||||
.getDaoForkBlock() |
||||
.ifPresent( |
||||
daoBlockNumber -> { |
||||
if (daoBlockNumber > 0) { |
||||
final ProtocolSpec<C> originalProtocolSpec = |
||||
protocolSchedule.getByBlockNumber(daoBlockNumber); |
||||
addProtocolSpec( |
||||
protocolSchedule, |
||||
OptionalLong.of(daoBlockNumber), |
||||
MainnetProtocolSpecs.daoRecoveryInitDefinition()); |
||||
addProtocolSpec( |
||||
protocolSchedule, |
||||
OptionalLong.of(daoBlockNumber + 1), |
||||
MainnetProtocolSpecs.daoRecoveryTransitionDefinition()); |
||||
|
||||
// Return to the previous protocol spec after the dao fork has completed.
|
||||
protocolSchedule.putMilestone(daoBlockNumber + 10, originalProtocolSpec); |
||||
} |
||||
}); |
||||
|
||||
addProtocolSpec( |
||||
protocolSchedule, |
||||
config.getTangerineWhistleBlockNumber(), |
||||
MainnetProtocolSpecs.tangerineWhistleDefinition()); |
||||
addProtocolSpec( |
||||
protocolSchedule, |
||||
config.getSpuriousDragonBlockNumber(), |
||||
MainnetProtocolSpecs.spuriousDragonDefinition(chainId)); |
||||
addProtocolSpec( |
||||
protocolSchedule, |
||||
config.getByzantiumBlockNumber(), |
||||
MainnetProtocolSpecs.byzantiumDefinition(chainId)); |
||||
addProtocolSpec( |
||||
protocolSchedule, |
||||
config.getConstantinopleBlockNumber(), |
||||
MainnetProtocolSpecs.constantinopleDefinition(chainId)); |
||||
|
||||
return protocolSchedule; |
||||
} |
||||
|
||||
private void addProtocolSpec( |
||||
final MutableProtocolSchedule<C> protocolSchedule, |
||||
final OptionalLong blockNumber, |
||||
final ProtocolSpecBuilder<Void> definition) { |
||||
blockNumber.ifPresent( |
||||
number -> |
||||
protocolSchedule.putMilestone( |
||||
number, protocolSpecAdapter.apply(definition).build(protocolSchedule))); |
||||
} |
||||
} |
Loading…
Reference in new issue