Skip to content

Commit

Permalink
ETC Atlantis fork
Browse files Browse the repository at this point in the history
Code to support ECIP 1054: Atlantis EVM and Protocol Upgrades

Signed-off-by: edwardmack <ed@edwardmack.com>
  • Loading branch information
edwardmack committed Nov 9, 2019
1 parent b610466 commit 9e895c9
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,18 @@ public interface GenesisConfigOptions {
*/
OptionalLong getDefuseDifficultyBombBlockNumber();

/**
* Block number for Atlantis fork on Classic network Note, this fork happen after Defuse
* Difficulty Bomb fork and before Agharta fork ECIP-1054: Atlantis EVM and Protocol Upgrades
* Enable the outstanding Ethereum Foundation Spurious Dragon and Byzantium network protocol
* upgrades for the Ethereum Classic network.
*
* @see <a
* href="https://ecips.ethereumclassic.org/ECIPs/ecip-1054">https://ecips.ethereumclassic.org/ECIPs/ecip-1054</a>
* @return block number for Atlantis fork on Classic network
*/
OptionalLong getAtlantisBlockNumber();

Optional<BigInteger> getChainId();

OptionalInt getContractSizeLimit();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,11 @@ public OptionalLong getDefuseDifficultyBombBlockNumber() {
return getOptionalLong("ecip1041block");
}

@Override
public OptionalLong getAtlantisBlockNumber() {
return getOptionalLong("atlantisblock");
}

@Override
public Optional<BigInteger> getChainId() {
return getOptionalBigInteger("chainid");
Expand Down
1 change: 1 addition & 0 deletions config/src/main/resources/classic.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"diehardBlock": 3000000,
"gothamBlock": 5000001,
"ecip1041Block": 5900000,
"atlantisBlock": 8772000,
"ethash": {

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions {
private OptionalLong diehardBlockNumber = OptionalLong.empty();
private OptionalLong gothamBlockNumber = OptionalLong.empty();
private OptionalLong defuseDifficultyBombBlockNumber = OptionalLong.empty();
private OptionalLong atlantisBlockNumber = OptionalLong.empty();
private Optional<BigInteger> chainId = Optional.empty();
private OptionalInt contractSizeLimit = OptionalInt.empty();
private OptionalInt stackSizeLimit = OptionalInt.empty();
Expand Down Expand Up @@ -151,6 +152,11 @@ public OptionalLong getDefuseDifficultyBombBlockNumber() {
return defuseDifficultyBombBlockNumber;
}

@Override
public OptionalLong getAtlantisBlockNumber() {
return atlantisBlockNumber;
}

@Override
public OptionalInt getContractSizeLimit() {
return contractSizeLimit;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*/
package org.hyperledger.besu.ethereum.mainnet;

import org.hyperledger.besu.ethereum.core.Hash;
import org.hyperledger.besu.util.uint.UInt256;

import java.math.BigInteger;
Expand Down Expand Up @@ -64,6 +65,29 @@ public abstract class ClassicDifficultyCalculators {
return difficulty;
};

public static DifficultyCalculator<Void> EIP100 =
(time, parent, protocolContext) -> {
final BigInteger parentDifficulty = difficulty(parent.getDifficulty());
final boolean hasOmmers = !parent.getOmmersHash().equals(Hash.EMPTY_LIST_HASH);
final BigInteger difficulty =
ensureMinimumDifficulty(
BigInteger.valueOf(byzantiumX(time, parent.getTimestamp(), hasOmmers))
.multiply(parentDifficulty.divide(DIFFICULTY_BOUND_DIVISOR))
.add(parentDifficulty));
return difficulty;
};

private static long byzantiumX(
final long blockTime, final long parentTime, final boolean hasOmmers) {
long x = (blockTime - parentTime) / 9L;
if (hasOmmers) {
x = 2 - x;
} else {
x = 1 - x;
}
return Math.max(x, -99L);
}

private static BigInteger adjustForDifficultyDelay(
final long periodCount, final BigInteger difficulty) {
return difficulty.add(BIGINT_2.pow(Ints.checkedCast(periodCount - DELAY - 2)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,15 @@
*/
package org.hyperledger.besu.ethereum.mainnet;

import org.hyperledger.besu.ethereum.core.Account;
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
import org.hyperledger.besu.ethereum.core.Wei;
import org.hyperledger.besu.ethereum.core.WorldState;
import org.hyperledger.besu.ethereum.mainnet.contractvalidation.MaxCodeSizeRule;
import org.hyperledger.besu.ethereum.vm.MessageFrame;

import java.math.BigInteger;
import java.util.Collections;
import java.util.Optional;
import java.util.OptionalInt;

Expand Down Expand Up @@ -83,4 +89,60 @@ public static ProtocolSpecBuilder<Void> defuseDifficultyBombDefinition(
gasCalculator -> new MainnetTransactionValidator(gasCalculator, true, chainId))
.name("DefuseDifficultyBomb");
}

public static ProtocolSpecBuilder<Void> atlantisDefinition(
final Optional<BigInteger> chainId,
final OptionalInt configContractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason) {
final int contractSizeLimit =
configContractSizeLimit.orElse(MainnetProtocolSpecs.SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT);
final int stackSizeLimit = configStackSizeLimit.orElse(MessageFrame.DEFAULT_MAX_STACK_SIZE);
return gothamDefinition(chainId, configContractSizeLimit, configStackSizeLimit)
.evmBuilder(MainnetEvmRegistries::byzantium)
.skipZeroBlockRewards(true)
.messageCallProcessorBuilder(
(evm, precompileContractRegistry) ->
new MainnetMessageCallProcessor(evm, precompileContractRegistry))
.precompileContractRegistryBuilder(MainnetPrecompiledContractRegistries::byzantium)
.difficultyCalculator(ClassicDifficultyCalculators.EIP100)
.transactionReceiptFactory(
enableRevertReason
? ClassicProtocolSpecs::byzantiumTransactionReceiptFactoryWithReasonEnabled
: ClassicProtocolSpecs::byzantiumTransactionReceiptFactory)
.contractCreationProcessorBuilder(
(gasCalculator, evm) ->
new MainnetContractCreationProcessor(
gasCalculator,
evm,
true,
Collections.singletonList(MaxCodeSizeRule.of(contractSizeLimit)),
1))
.transactionProcessorBuilder(
(gasCalculator,
transactionValidator,
contractCreationProcessor,
messageCallProcessor) ->
new MainnetTransactionProcessor(
gasCalculator,
transactionValidator,
contractCreationProcessor,
messageCallProcessor,
true,
stackSizeLimit,
Account.DEFAULT_VERSION))
.name("Atlantis");
}

private static TransactionReceipt byzantiumTransactionReceiptFactory(
final TransactionProcessor.Result result, final WorldState worldState, final long gasUsed) {
return new TransactionReceipt(
result.isSuccessful() ? 1 : 0, gasUsed, result.getLogs(), Optional.empty());
}

private static TransactionReceipt byzantiumTransactionReceiptFactoryWithReasonEnabled(
final TransactionProcessor.Result result, final WorldState worldState, final long gasUsed) {
return new TransactionReceipt(
result.isSuccessful() ? 1 : 0, gasUsed, result.getLogs(), result.getRevertReason());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,14 @@ public ProtocolSchedule<C> createProtocolSchedule() {
config.getDefuseDifficultyBombBlockNumber(),
ClassicProtocolSpecs.defuseDifficultyBombDefinition(
chainId, config.getContractSizeLimit(), config.getEvmStackSize()));
addProtocolSpec(
protocolSchedule,
config.getAtlantisBlockNumber(),
ClassicProtocolSpecs.atlantisDefinition(
chainId,
config.getContractSizeLimit(),
config.getEvmStackSize(),
isRevertReasonEnabled));

LOG.info("Protocol schedule created with milestones: {}", protocolSchedule.listMilestones());
return protocolSchedule;
Expand Down Expand Up @@ -221,6 +229,14 @@ private long validateForkOrder(
}

private void validateForkOrdering() {
if (config.getDaoForkBlock().isEmpty()) {
validateClassicForkOrdering();
} else {
validateEthereumForkOrdering();
}
}

private void validateEthereumForkOrdering() {
long lastForkBlock = 0;
lastForkBlock = validateForkOrder("Homestead", config.getHomesteadBlockNumber(), lastForkBlock);
lastForkBlock = validateForkOrder("DaoFork", config.getDaoForkBlock(), lastForkBlock);
Expand All @@ -238,4 +254,19 @@ private void validateForkOrdering() {
lastForkBlock = validateForkOrder("Istanbul", config.getIstanbulBlockNumber(), lastForkBlock);
assert (lastForkBlock >= 0);
}

private void validateClassicForkOrdering() {
long lastForkBlock = 0;
lastForkBlock = validateForkOrder("Homestead", config.getHomesteadBlockNumber(), lastForkBlock);
lastForkBlock =
validateForkOrder(
"ClassicTangerineWhistle", config.getEcip1015BlockNumber(), lastForkBlock);
lastForkBlock = validateForkOrder("DieHard", config.getDieHardBlockNumber(), lastForkBlock);
lastForkBlock = validateForkOrder("Gotham", config.getGothamBlockNumber(), lastForkBlock);
lastForkBlock =
validateForkOrder(
"DefuseDifficultyBomb", config.getDefuseDifficultyBombBlockNumber(), lastForkBlock);
lastForkBlock = validateForkOrder("Atlantis", config.getAtlantisBlockNumber(), lastForkBlock);
assert (lastForkBlock >= 0);
}
}

0 comments on commit 9e895c9

Please sign in to comment.