From 7a7da0c11fb6e036a260af14d0f2a60c3cf6378e Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Wed, 16 Aug 2017 12:38:10 +0600 Subject: [PATCH 1/3] Update TransitionTests with new test format --- .../jsontestsuite/GitHubJSONTestSuite.java | 25 ++++++++- .../jsontestsuite/GitHubTestNetTest.java | 56 ++++++++----------- .../suite/BlockchainTestSuite.java | 9 +++ 3 files changed, 56 insertions(+), 34 deletions(-) diff --git a/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/GitHubJSONTestSuite.java b/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/GitHubJSONTestSuite.java index 7c6a551f33..cbc229e07b 100644 --- a/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/GitHubJSONTestSuite.java +++ b/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/GitHubJSONTestSuite.java @@ -19,6 +19,7 @@ import org.ethereum.config.BlockchainNetConfig; import org.ethereum.config.blockchain.*; +import org.ethereum.config.net.BaseNetConfig; import org.ethereum.jsontestsuite.suite.*; import org.ethereum.jsontestsuite.suite.runners.TransactionTestRunner; import org.json.simple.JSONObject; @@ -263,14 +264,36 @@ public enum Network { EIP150, EIP158, Byzantium, - Constantinople; + Constantinople, + + // Transition networks + FrontierToHomesteadAt5, + HomesteadToDaoAt5, + HomesteadToEIP150At5; public BlockchainNetConfig getConfig() { switch (this) { + case Frontier: return new FrontierConfig(); case Homestead: return new HomesteadConfig(); case EIP150: return new Eip150HFConfig(new DaoHFConfig()); case EIP158: return new Eip160HFConfig(new DaoHFConfig()); + + case FrontierToHomesteadAt5: return new BaseNetConfig() {{ + add(0, new FrontierConfig()); + add(5, new HomesteadConfig()); + }}; + + case HomesteadToDaoAt5: return new BaseNetConfig() {{ + add(0, new HomesteadConfig()); + add(5, new DaoHFConfig(new HomesteadConfig(), 5)); + }}; + + case HomesteadToEIP150At5: return new BaseNetConfig() {{ + add(0, new HomesteadConfig()); + add(5, new Eip150HFConfig(new HomesteadConfig())); + }}; + default: throw new IllegalArgumentException("Unknown network value: " + this.name()); } } diff --git a/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/GitHubTestNetTest.java b/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/GitHubTestNetTest.java index 4bacd14558..412c2bf73b 100644 --- a/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/GitHubTestNetTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/GitHubTestNetTest.java @@ -17,57 +17,47 @@ */ package org.ethereum.jsontestsuite; -import org.ethereum.config.SystemProperties; -import org.ethereum.config.blockchain.DaoHFConfig; -import org.ethereum.config.blockchain.Eip150HFConfig; -import org.ethereum.config.blockchain.FrontierConfig; -import org.ethereum.config.blockchain.HomesteadConfig; -import org.ethereum.config.net.BaseNetConfig; -import org.ethereum.config.net.MainNetConfig; -import org.ethereum.jsontestsuite.suite.JSONReader; -import org.json.simple.parser.ParseException; +import org.ethereum.jsontestsuite.suite.BlockchainTestSuite; import org.junit.*; import org.junit.runners.MethodSorters; import java.io.IOException; -import java.util.Collections; @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class GitHubTestNetTest { - //SHACOMMIT of tested commit, ethereum/tests.git - public String shacommit = "9ed33d7440f13c09ce7f038f92abd02d23b26f0d"; + static String commitSHA = "85f6d7cc01b6bd04e071f5ba579fc675cfd2043b"; + static String treeSHA = "0af522c09e8a264f651f5a4715301381c14784d7"; // https://github.com/ethereum/tests/tree/develop/BlockchainTests/TransitionTests - @Before - public void setup() { - SystemProperties.getDefault().setGenesisInfo("frontier.json"); - SystemProperties.getDefault().setBlockchainConfig(new BaseNetConfig() {{ - add(0, new FrontierConfig()); - add(5, new HomesteadConfig()); - add(8, new DaoHFConfig(new HomesteadConfig(), 8)); - add(10, new Eip150HFConfig(new DaoHFConfig(new HomesteadConfig(), 8))); + static BlockchainTestSuite suite; - }}); + @BeforeClass + public static void setup() { + suite = new BlockchainTestSuite(treeSHA, commitSHA); } - @After - public void clean() { - SystemProperties.getDefault().setBlockchainConfig(MainNetConfig.INSTANCE); + @Test + @Ignore + // this method is mostly for hands-on convenient testing + // using this method turn off initializing of BlockchainTestSuite to avoid unnecessary GitHub API hits + public void bcTransitionSingle() throws IOException { + BlockchainTestSuite.runSingle( + "TransitionTests/bcHomesteadToDao/DaoTransactions.json", commitSHA); } @Test - public void bcEIP150Test() throws ParseException, IOException { - String json = JSONReader.loadJSONFromCommit("BlockchainTests/TestNetwork/bcEIP150Test.json", shacommit); - GitHubJSONTestSuite.runGitHubJsonBlockTest(json, Collections.EMPTY_SET); + public void bcFrontierToHomestead() throws IOException { + suite.runAll("TransitionTests/bcFrontierToHomestead", GitHubJSONTestSuite.Network.FrontierToHomesteadAt5); } + @Test - public void bcSimpleTransitionTest() throws ParseException, IOException { - String json = JSONReader.loadJSONFromCommit("BlockchainTests/TestNetwork/bcSimpleTransitionTest.json", shacommit); - GitHubJSONTestSuite.runGitHubJsonBlockTest(json, Collections.EMPTY_SET); + @Ignore // TODO fix it + public void bcHomesteadToDao() throws IOException { + suite.runAll("TransitionTests/bcHomesteadToDao", GitHubJSONTestSuite.Network.HomesteadToDaoAt5); } + @Test - public void bcTheDaoTest() throws ParseException, IOException { - String json = JSONReader.loadJSONFromCommit("BlockchainTests/TestNetwork/bcTheDaoTest.json", shacommit); - GitHubJSONTestSuite.runGitHubJsonBlockTest(json, Collections.EMPTY_SET); + public void bcHomesteadToEIP150() throws IOException { + suite.runAll("TransitionTests/bcHomesteadToEIP150", GitHubJSONTestSuite.Network.HomesteadToEIP150At5); } } diff --git a/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/suite/BlockchainTestSuite.java b/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/suite/BlockchainTestSuite.java index b5f1cffbce..736e68816b 100644 --- a/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/suite/BlockchainTestSuite.java +++ b/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/suite/BlockchainTestSuite.java @@ -33,6 +33,10 @@ public BlockchainTestSuite(String treeSHA, String commitSHA, GitHubJSONTestSuite this.networks = networks; } + public BlockchainTestSuite(String treeSHA, String commitSHA) { + this(treeSHA, commitSHA, GitHubJSONTestSuite.Network.values()); + } + private static void run(List checkFiles, String commitSHA, GitHubJSONTestSuite.Network[] networks) throws IOException { @@ -142,4 +146,9 @@ public static void runSingle(String testFile, String commitSHA, logger.info(" " + testFile); run(Collections.singletonList(testFile), commitSHA, new GitHubJSONTestSuite.Network[] { network }); } + + public static void runSingle(String testFile, String commitSHA) throws IOException { + logger.info(" " + testFile); + run(Collections.singletonList(testFile), commitSHA, GitHubJSONTestSuite.Network.values()); + } } From 1139a83bf0dfaefd35d63e4fb1d447155edade69 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Wed, 16 Aug 2017 15:34:47 +0600 Subject: [PATCH 2/3] EIP-100 add uncles adjustment to the difficulty --- .../org/ethereum/config/BlockchainConfig.java | 5 +++ .../config/blockchain/AbstractConfig.java | 2 - .../config/blockchain/ByzantiumConfig.java | 39 +++++++++++++++++++ .../ethereum/config/blockchain/ETCFork3M.java | 3 +- .../config/blockchain/Eip150HFConfig.java | 5 +++ .../config/blockchain/HomesteadConfig.java | 2 +- .../config/blockchain/OlympicConfig.java | 2 +- .../java/org/ethereum/core/BlockHeader.java | 6 ++- 8 files changed, 58 insertions(+), 6 deletions(-) create mode 100644 ethereumj-core/src/main/java/org/ethereum/config/blockchain/ByzantiumConfig.java diff --git a/ethereumj-core/src/main/java/org/ethereum/config/BlockchainConfig.java b/ethereumj-core/src/main/java/org/ethereum/config/BlockchainConfig.java index 431d56a379..c889d08dab 100644 --- a/ethereumj-core/src/main/java/org/ethereum/config/BlockchainConfig.java +++ b/ethereumj-core/src/main/java/org/ethereum/config/BlockchainConfig.java @@ -52,6 +52,11 @@ public interface BlockchainConfig { */ BigInteger calcDifficulty(BlockHeader curBlock, BlockHeader parent); + /** + * Calculates difficulty adjustment to target mean block time + */ + BigInteger getCalcDifficultyMultiplier(BlockHeader curBlock, BlockHeader parent); + /** * Calculates transaction gas fee */ diff --git a/ethereumj-core/src/main/java/org/ethereum/config/blockchain/AbstractConfig.java b/ethereumj-core/src/main/java/org/ethereum/config/blockchain/AbstractConfig.java index 0d5a562a7b..ad9eba8a90 100644 --- a/ethereumj-core/src/main/java/org/ethereum/config/blockchain/AbstractConfig.java +++ b/ethereumj-core/src/main/java/org/ethereum/config/blockchain/AbstractConfig.java @@ -100,8 +100,6 @@ public BigInteger calcDifficulty(BlockHeader curBlock, BlockHeader parent) { return difficulty; } - protected abstract BigInteger getCalcDifficultyMultiplier(BlockHeader curBlock, BlockHeader parent); - protected int getExplosion(BlockHeader curBlock, BlockHeader parent) { int periodCount = (int) (curBlock.getNumber() / getConstants().getEXP_DIFFICULTY_PERIOD()); return periodCount - 2; diff --git a/ethereumj-core/src/main/java/org/ethereum/config/blockchain/ByzantiumConfig.java b/ethereumj-core/src/main/java/org/ethereum/config/blockchain/ByzantiumConfig.java new file mode 100644 index 0000000000..3dcb50eda9 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/config/blockchain/ByzantiumConfig.java @@ -0,0 +1,39 @@ +package org.ethereum.config.blockchain; + +import org.ethereum.config.BlockchainConfig; +import org.ethereum.config.Constants; +import org.ethereum.core.Block; +import org.ethereum.core.BlockHeader; +import org.ethereum.core.Repository; +import org.spongycastle.util.encoders.Hex; + +import java.math.BigInteger; + +/** + * EIPs included in the Hard Fork: + *
    + *
  • 100 - Change difficulty adjustment to target mean block time including uncles
  • + *
  • 140 - REVERT instruction in the Ethereum Virtual Machine
  • + *
  • 196 - Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128
  • + *
  • 197 - Precompiled contracts for optimal Ate pairing check on the elliptic curve alt_bn128
  • + *
  • 198 - Precompiled contract for bigint modular exponentiation
  • + *
  • 211 - New opcodes: RETURNDATASIZE and RETURNDATACOPY
  • + *
  • 214 - New opcode STATICCALL
  • + *
  • 658 - Embedding transaction return data in receipts
  • + *
+ * + * @author Mikhail Kalinin + * @since 14.08.2017 + */ +public class ByzantiumConfig extends Eip160HFConfig { + + public ByzantiumConfig(BlockchainConfig parent) { + super(parent); + } + + @Override + public BigInteger getCalcDifficultyMultiplier(BlockHeader curBlock, BlockHeader parent) { + long unclesAdj = parent.hasUncles() ? 2 : 1; + return BigInteger.valueOf(Math.max(unclesAdj - (curBlock.getTimestamp() - parent.getTimestamp()) / 9, -99)); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/config/blockchain/ETCFork3M.java b/ethereumj-core/src/main/java/org/ethereum/config/blockchain/ETCFork3M.java index 82b8b834e1..77f4a18dd9 100644 --- a/ethereumj-core/src/main/java/org/ethereum/config/blockchain/ETCFork3M.java +++ b/ethereumj-core/src/main/java/org/ethereum/config/blockchain/ETCFork3M.java @@ -66,7 +66,8 @@ public BigInteger calcDifficulty(BlockHeader curBlock, BlockHeader parent) { return difficulty; } - protected BigInteger getCalcDifficultyMultiplier(BlockHeader curBlock, BlockHeader parent) { + @Override + public BigInteger getCalcDifficultyMultiplier(BlockHeader curBlock, BlockHeader parent) { return BigInteger.valueOf(Math.max(1 - (curBlock.getTimestamp() - parent.getTimestamp()) / 10, -99)); } diff --git a/ethereumj-core/src/main/java/org/ethereum/config/blockchain/Eip150HFConfig.java b/ethereumj-core/src/main/java/org/ethereum/config/blockchain/Eip150HFConfig.java index 7e5d1354f2..7e963ff137 100644 --- a/ethereumj-core/src/main/java/org/ethereum/config/blockchain/Eip150HFConfig.java +++ b/ethereumj-core/src/main/java/org/ethereum/config/blockchain/Eip150HFConfig.java @@ -87,6 +87,11 @@ public BigInteger calcDifficulty(BlockHeader curBlock, BlockHeader parent) { return this.parent.calcDifficulty(curBlock, parent); } + @Override + public BigInteger getCalcDifficultyMultiplier(BlockHeader curBlock, BlockHeader parent) { + return this.parent.getCalcDifficultyMultiplier(curBlock, parent); + } + @Override public long getTransactionCost(Transaction tx) { return parent.getTransactionCost(tx); diff --git a/ethereumj-core/src/main/java/org/ethereum/config/blockchain/HomesteadConfig.java b/ethereumj-core/src/main/java/org/ethereum/config/blockchain/HomesteadConfig.java index 45a63f3047..9bfd4648cf 100644 --- a/ethereumj-core/src/main/java/org/ethereum/config/blockchain/HomesteadConfig.java +++ b/ethereumj-core/src/main/java/org/ethereum/config/blockchain/HomesteadConfig.java @@ -52,7 +52,7 @@ public HomesteadConfig(Constants constants) { } @Override - protected BigInteger getCalcDifficultyMultiplier(BlockHeader curBlock, BlockHeader parent) { + public BigInteger getCalcDifficultyMultiplier(BlockHeader curBlock, BlockHeader parent) { return BigInteger.valueOf(Math.max(1 - (curBlock.getTimestamp() - parent.getTimestamp()) / 10, -99)); } diff --git a/ethereumj-core/src/main/java/org/ethereum/config/blockchain/OlympicConfig.java b/ethereumj-core/src/main/java/org/ethereum/config/blockchain/OlympicConfig.java index fd3bb40f93..82f8d8eb97 100644 --- a/ethereumj-core/src/main/java/org/ethereum/config/blockchain/OlympicConfig.java +++ b/ethereumj-core/src/main/java/org/ethereum/config/blockchain/OlympicConfig.java @@ -37,7 +37,7 @@ public OlympicConfig(Constants constants) { } @Override - protected BigInteger getCalcDifficultyMultiplier(BlockHeader curBlock, BlockHeader parent) { + public BigInteger getCalcDifficultyMultiplier(BlockHeader curBlock, BlockHeader parent) { return BigInteger.valueOf(curBlock.getTimestamp() >= parent.getTimestamp() + getConstants().getDURATION_LIMIT() ? -1 : 1); } diff --git a/ethereumj-core/src/main/java/org/ethereum/core/BlockHeader.java b/ethereumj-core/src/main/java/org/ethereum/core/BlockHeader.java index 125d016a7d..976393c17f 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/BlockHeader.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/BlockHeader.java @@ -148,7 +148,7 @@ public BlockHeader(byte[] parentHash, byte[] unclesHash, byte[] coinbase, this.extraData = extraData; this.mixHash = mixHash; this.nonce = nonce; - this.stateRoot = HashUtil.EMPTY_TRIE_HASH; + this.stateRoot = EMPTY_TRIE_HASH; } public boolean isGenesis() { @@ -374,6 +374,10 @@ public BigInteger calcDifficulty(BlockchainNetConfig config, BlockHeader parent) calcDifficulty(this, parent); } + public boolean hasUncles() { + return !FastByteComparisons.equal(unclesHash, EMPTY_TRIE_HASH); + } + public String toString() { return toStringWithSuffix("\n"); } From d0aee4b5e556759e1a88c63cfc98b1f1cf67f64c Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Wed, 16 Aug 2017 18:58:08 +0600 Subject: [PATCH 3/3] Fix difficulty issue related to ByzantiumConfig inheritance --- .../config/blockchain/ByzantiumConfig.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/ethereumj-core/src/main/java/org/ethereum/config/blockchain/ByzantiumConfig.java b/ethereumj-core/src/main/java/org/ethereum/config/blockchain/ByzantiumConfig.java index 3dcb50eda9..92d4fe8da3 100644 --- a/ethereumj-core/src/main/java/org/ethereum/config/blockchain/ByzantiumConfig.java +++ b/ethereumj-core/src/main/java/org/ethereum/config/blockchain/ByzantiumConfig.java @@ -9,6 +9,8 @@ import java.math.BigInteger; +import static org.ethereum.util.BIUtil.max; + /** * EIPs included in the Hard Fork: *
    @@ -31,6 +33,30 @@ public ByzantiumConfig(BlockchainConfig parent) { super(parent); } + @Override + public BigInteger calcDifficulty(BlockHeader curBlock, BlockHeader parent) { + BigInteger pd = parent.getDifficultyBI(); + BigInteger quotient = pd.divide(getConstants().getDIFFICULTY_BOUND_DIVISOR()); + + BigInteger sign = getCalcDifficultyMultiplier(curBlock, parent); + + BigInteger fromParent = pd.add(quotient.multiply(sign)); + BigInteger difficulty = max(getConstants().getMINIMUM_DIFFICULTY(), fromParent); + + int explosion = getExplosion(curBlock, parent); + + if (explosion >= 0) { + difficulty = max(getConstants().getMINIMUM_DIFFICULTY(), difficulty.add(BigInteger.ONE.shiftLeft(explosion))); + } + + return difficulty; + } + + protected int getExplosion(BlockHeader curBlock, BlockHeader parent) { + int periodCount = (int) (curBlock.getNumber() / getConstants().getEXP_DIFFICULTY_PERIOD()); + return periodCount - 2; + } + @Override public BigInteger getCalcDifficultyMultiplier(BlockHeader curBlock, BlockHeader parent) { long unclesAdj = parent.hasUncles() ? 2 : 1;