Skip to content

Commit

Permalink
Merge c3191f3 into 2601bc4
Browse files Browse the repository at this point in the history
  • Loading branch information
zilm13 committed Sep 19, 2018
2 parents 2601bc4 + c3191f3 commit 7106d77
Show file tree
Hide file tree
Showing 9 changed files with 282 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
*/
package org.ethereum.config;

import org.ethereum.util.blockchain.EtherUtil;

import java.math.BigInteger;

/**
Expand All @@ -37,7 +39,7 @@ public class Constants {

private static final int BEST_NUMBER_DIFF_LIMIT = 100;

private static final BigInteger BLOCK_REWARD = new BigInteger("1500000000000000000");
private static final BigInteger BLOCK_REWARD = EtherUtil.convert(1500, EtherUtil.Unit.FINNEY); // 1.5 ETH

private static final BigInteger SECP256K1N = new BigInteger("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@
import org.ethereum.config.BlockchainConfig;
import org.ethereum.config.Constants;
import org.ethereum.config.ConstantsAdapter;
import org.ethereum.core.Block;
import org.ethereum.core.BlockHeader;
import org.ethereum.core.Repository;
import org.ethereum.util.blockchain.EtherUtil;

import java.math.BigInteger;

Expand Down Expand Up @@ -51,7 +50,7 @@ public class ByzantiumConfig extends Eip160HFConfig {
public ByzantiumConfig(BlockchainConfig parent) {
super(parent);
constants = new ConstantsAdapter(super.getConstants()) {
private final BigInteger BLOCK_REWARD = new BigInteger("3000000000000000000");
private final BigInteger BLOCK_REWARD = EtherUtil.convert(3, EtherUtil.Unit.ETHER);

@Override
public BigInteger getBLOCK_REWARD() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,17 @@
package org.ethereum.config.blockchain;

import org.ethereum.config.BlockchainConfig;
import org.ethereum.config.Constants;
import org.ethereum.config.ConstantsAdapter;
import org.ethereum.core.BlockHeader;
import org.ethereum.util.blockchain.EtherUtil;

import java.math.BigInteger;

/**
* EIPs included in the Constantinople Hard Fork:
* <ul>
* <li>1234 - Constantinople Difficulty Bomb Delay and Block Reward Adjustment (2 ETH)</li>
* <li>145 - Bitwise shifting instructions in EVM</li>
* <li>1014 - Skinny CREATE2</li>
* <li>1052 - EXTCODEHASH opcode</li>
Expand All @@ -30,8 +37,29 @@
*/
public class ConstantinopleConfig extends ByzantiumConfig {

private final Constants constants;

public ConstantinopleConfig(BlockchainConfig parent) {
super(parent);
constants = new ConstantsAdapter(super.getConstants()) {
private final BigInteger BLOCK_REWARD = EtherUtil.convert(2, EtherUtil.Unit.ETHER);

@Override
public BigInteger getBLOCK_REWARD() {
return BLOCK_REWARD;
}
};
}

@Override
public Constants getConstants() {
return constants;
}

@Override
protected int getExplosion(BlockHeader curBlock, BlockHeader parent) {
int periodCount = (int) (Math.max(0, curBlock.getNumber() - 5_000_000) / getConstants().getEXP_DIFFICULTY_PERIOD());
return periodCount - 2;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import org.ethereum.config.Constants;
import org.ethereum.core.Transaction;
import org.ethereum.util.blockchain.EtherUtil;

import java.math.BigInteger;

Expand All @@ -28,7 +29,7 @@
public class FrontierConfig extends OlympicConfig {

public static class FrontierConstants extends Constants {
private static final BigInteger BLOCK_REWARD = new BigInteger("5000000000000000000");
private static final BigInteger BLOCK_REWARD = EtherUtil.convert(5, EtherUtil.Unit.ETHER);

@Override
public int getDURATION_LIMIT() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,20 @@ public Integer getChainId() {
}
candidates.add(lastCandidate);
}
if (config.constantinopleBlock != null) {
if (config.chainId != null) {
final int chainId = config.chainId;
lastCandidate = Pair.of(config.constantinopleBlock, new ConstantinopleConfig(lastCandidate.getRight()) {
@Override
public Integer getChainId() {
return chainId;
}
});
} else {
lastCandidate = Pair.of(config.constantinopleBlock, new ConstantinopleConfig(lastCandidate.getRight()));
}
candidates.add(lastCandidate);
}
}

{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class GenesisConfig {
public boolean daoForkSupport;
public Integer eip158Block;
public Integer byzantiumBlock;
public Integer constantinopleBlock;
public Integer chainId;

// EthereumJ private options
Expand All @@ -43,6 +44,7 @@ public static class HashValidator {

public boolean isCustomConfig() {
return homesteadBlock != null || daoForkBlock != null || eip150Block != null ||
eip155Block != null || eip158Block != null || byzantiumBlock != null;
eip155Block != null || eip158Block != null || byzantiumBlock != null ||
constantinopleBlock != null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import org.ethereum.config.Constants;
import org.ethereum.config.ConstantsAdapter;
import org.ethereum.core.BlockHeader;
import org.junit.Ignore;
import org.junit.Test;
import org.spongycastle.util.encoders.Hex;

Expand Down Expand Up @@ -86,7 +85,6 @@ public void testDifficultyAdjustedForParentBlockHavingUncles() throws Exception
}

@Test
@Ignore
public void testEtherscanIoBlock4490790() throws Exception {
ByzantiumConfig byzantiumConfig = new ByzantiumConfig(new TestBlockchainConfig());

Expand All @@ -104,8 +102,6 @@ public void testEtherscanIoBlock4490790() throws Exception {
.build();

BigInteger minimumDifficulty = byzantiumConfig.calcDifficulty(current, parent);
assertEquals(BlockHeaderBuilder.parse("1,378,600,421,631,340"), minimumDifficulty);

BigInteger actualDifficultyOnEtherscan = BlockHeaderBuilder.parse("1,377,927,933,620,791");
assertTrue(actualDifficultyOnEtherscan.compareTo(minimumDifficulty) > -1);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
/*
* Copyright (c) [2017] [ <ether.camp> ]
* This file is part of the ethereumJ library.
*
* The ethereumJ library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The ethereumJ library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the ethereumJ library. If not, see <http://www.gnu.org/licenses/>.
*
*
*/

package org.ethereum.config.blockchain;

import org.ethereum.config.Constants;
import org.ethereum.config.ConstantsAdapter;
import org.ethereum.core.BlockHeader;
import org.ethereum.util.blockchain.EtherUtil;
import org.junit.Test;

import java.math.BigInteger;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

@SuppressWarnings("SameParameterValue")
public class ConstantinopleConfigTest {

private static final byte[] FAKE_HASH = {11, 12};
private static final ConstantinopleConfig constantinopleConfig = new ConstantinopleConfig(new TestBlockchainConfig());

@Test
public void testRelatedEip() throws Exception {
// Byzantium
assertTrue(constantinopleConfig.eip198());
assertTrue(constantinopleConfig.eip206());
assertTrue(constantinopleConfig.eip211());
assertTrue(constantinopleConfig.eip212());
assertTrue(constantinopleConfig.eip213());
assertTrue(constantinopleConfig.eip214());
assertTrue(constantinopleConfig.eip658());

// Constantinople
assertTrue(constantinopleConfig.eip145());
assertTrue(constantinopleConfig.eip1014());
assertTrue(constantinopleConfig.eip1052());
assertTrue(constantinopleConfig.eip1283());

ByzantiumConfig byzantiumConfig = new ByzantiumConfig(new TestBlockchainConfig());

// Constantinople eips in Byzantium
assertFalse(byzantiumConfig.eip145());
assertFalse(byzantiumConfig.eip1014());
assertFalse(byzantiumConfig.eip1052());
assertFalse(byzantiumConfig.eip1283());
}


@Test
public void testDifficultyWithoutExplosion() throws Exception {
BlockHeader parent = new BlockHeaderBuilder(FAKE_HASH, 0L, 1_000_000).build();
BlockHeader current = new BlockHeaderBuilder(parent.getHash(), 1L, -1).build();

BigInteger difficulty = constantinopleConfig.calcDifficulty(current, parent);
assertEquals(BigInteger.valueOf(1_000_976), difficulty);
}

@Test
public void testDifficultyAdjustedForParentBlockHavingUncles() throws Exception {
BlockHeader parent = new BlockHeaderBuilder(FAKE_HASH, 0L, 0)
.withTimestamp(0L)
.withUncles(new byte[]{1, 2})
.build();
BlockHeader current = new BlockHeaderBuilder(parent.getHash(), 1L, 0)
.withTimestamp(9L)
.build();
assertEquals(1, constantinopleConfig.getCalcDifficultyMultiplier(current, parent).intValue());
}

@Test
public void testDifficultyWithExplosionShouldBeImpactedByBlockTimestamp() throws Exception {

BlockHeader parent = new BlockHeaderBuilder(new byte[]{11, 12}, 2_500_000, 8_388_608)
.withTimestamp(0)
.build();
BlockHeader current = new BlockHeaderBuilder(parent.getHash(), 2_500_001, 8_388_608)
.withTimestamp(10 * 60) // 10 minutes later, longer time: lowers difficulty
.build();

BigInteger difficulty = constantinopleConfig.calcDifficulty(current, parent);
assertEquals(BigInteger.valueOf(8126464), difficulty);


parent = new BlockHeaderBuilder(new byte[]{11, 12}, 2_500_000, 8_388_608)
.withTimestamp(0)
.build();
current = new BlockHeaderBuilder(parent.getHash(), 2_500_001, 8_388_608)
.withTimestamp(5) // 5 seconds later, shorter time: higher difficulty
.build();

difficulty = constantinopleConfig.calcDifficulty(current, parent);
assertEquals(BigInteger.valueOf(8396800), difficulty);
}

@Test
public void testDifficultyAboveBlock5MShouldTriggerExplosion() throws Exception {

int parentDifficulty = 268_435_456;
BlockHeader parent = new BlockHeaderBuilder(FAKE_HASH, 6_000_000, parentDifficulty).build();
BlockHeader current = new BlockHeaderBuilder(parent.getHash(), 6_000_001, -1).build();
int actualDifficulty = constantinopleConfig.calcDifficulty(current, parent).intValue();
int differenceWithoutExplosion = actualDifficulty - parentDifficulty;
assertEquals(262_400, differenceWithoutExplosion);

parent = new BlockHeaderBuilder(FAKE_HASH, 7_000_000, parentDifficulty).build();
current = new BlockHeaderBuilder(parent.getHash(), 7_000_001, -1).build();
actualDifficulty = constantinopleConfig.calcDifficulty(current, parent).intValue();
differenceWithoutExplosion = actualDifficulty - parentDifficulty;
assertEquals(524_288, differenceWithoutExplosion);

parent = new BlockHeaderBuilder(FAKE_HASH, 8_000_000, parentDifficulty).build();
current = new BlockHeaderBuilder(parent.getHash(), 8_000_001, -1).build();
actualDifficulty = constantinopleConfig.calcDifficulty(current, parent).intValue();
differenceWithoutExplosion = actualDifficulty - parentDifficulty;
assertEquals(268_697_600, differenceWithoutExplosion); // Explosion!
}

@Test
@SuppressWarnings("PointlessArithmeticExpression")
public void testCalcDifficultyMultiplier() throws Exception {
// Note; timestamps are in seconds
assertCalcDifficultyMultiplier(0L, 1L, 2);
assertCalcDifficultyMultiplier(0L, 5, 2); // 5 seconds
assertCalcDifficultyMultiplier(0L, 1 * 10, 1); // 10 seconds
assertCalcDifficultyMultiplier(0L, 2 * 10, -0); // 20 seconds
assertCalcDifficultyMultiplier(0L, 10 * 10, -9); // 100 seconds
assertCalcDifficultyMultiplier(0L, 60 * 10, -64); // 10 mins
assertCalcDifficultyMultiplier(0L, 60 * 12, -78); // 12 mins
}

private void assertCalcDifficultyMultiplier(long parentBlockTimestamp, long curBlockTimestamp, int expectedMultiplier) {
BlockHeader parent = new BlockHeaderBuilder(FAKE_HASH, 0L, 0)
.withTimestamp(parentBlockTimestamp)
.build();
BlockHeader current = new BlockHeaderBuilder(parent.getHash(), 1L, 0)
.withTimestamp(curBlockTimestamp)
.build();
assertEquals(expectedMultiplier, constantinopleConfig.getCalcDifficultyMultiplier(current, parent).intValue());
}


@Test
public void testExplosionChanges() throws Exception {

BlockHeader beforePauseBlock = new BlockHeaderBuilder(FAKE_HASH, 4_000_000, 0).build();
assertEquals(-2, constantinopleConfig.getExplosion(beforePauseBlock, null));

BlockHeader endOfIceAge = new BlockHeaderBuilder(FAKE_HASH, 5_000_000, 0).build();
assertEquals(-2, constantinopleConfig.getExplosion(endOfIceAge, null));

BlockHeader startExplodingBlock = new BlockHeaderBuilder(FAKE_HASH, 5_200_000, 0).build();
assertEquals(0, constantinopleConfig.getExplosion(startExplodingBlock, null));

startExplodingBlock = new BlockHeaderBuilder(FAKE_HASH, 6_000_000, 0).build();
assertEquals(8, constantinopleConfig.getExplosion(startExplodingBlock, null));

startExplodingBlock = new BlockHeaderBuilder(FAKE_HASH, 8_000_000, 0).build();
assertEquals(28, constantinopleConfig.getExplosion(startExplodingBlock, null));
}

@Test
public void testBlockReward() throws Exception {
ConstantinopleConfig constantinopleConfig2 = new ConstantinopleConfig(new TestBlockchainConfig() {
@Override
public Constants getConstants() {
return new ConstantsAdapter(super.getConstants()) {
@Override
public BigInteger getBLOCK_REWARD() {
// Make sure ConstantinopleConfig is not using parent's block reward
return BigInteger.TEN;
}
};
}
});
assertEquals(EtherUtil.convert(2, EtherUtil.Unit.ETHER), constantinopleConfig2.getConstants().getBLOCK_REWARD());
}
}

0 comments on commit 7106d77

Please sign in to comment.