From cad4e049797c46041327fd8ff0990e4d46df764a Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Tue, 21 Mar 2017 17:59:25 +0100 Subject: [PATCH 1/2] EIP100: New difficulty formula taking into account uncles in the parent block --- libethashseal/Ethash.cpp | 10 ++++++++-- libethcore/BlockHeader.h | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/libethashseal/Ethash.cpp b/libethashseal/Ethash.cpp index 0e9a56046de..ec2e8afd81c 100644 --- a/libethashseal/Ethash.cpp +++ b/libethashseal/Ethash.cpp @@ -194,8 +194,14 @@ u256 Ethash::calculateDifficulty(BlockHeader const& _bi, BlockHeader const& _par // Frontier-era difficulty adjustment target = _bi.timestamp() >= _parent.timestamp() + durationLimit ? _parent.difficulty() - (_parent.difficulty() / difficultyBoundDivisor) : (_parent.difficulty() + (_parent.difficulty() / difficultyBoundDivisor)); else - // Homestead-era difficulty adjustment - target = _parent.difficulty() + _parent.difficulty() / 2048 * max(1 - (bigint(_bi.timestamp()) - _parent.timestamp()) / 10, -99); + { + bigint const timestampDiff = bigint(_bi.timestamp()) - _parent.timestamp(); + bigint const adjFactor = _bi.number() < chainParams().u256Param("metropolisForkBlock") ? + max(1 - timestampDiff / 10, -99) : // Homestead-era difficulty adjustment + max((_parent.hasUncles() ? 2 : 1) - timestampDiff / 9, -99); // Metropolis-era difficulty adjustment + + target = _parent.difficulty() + _parent.difficulty() / 2048 * adjFactor; + } bigint o = target; unsigned periodCount = unsigned(_parent.number() + 1) / c_expDiffPeriod; diff --git a/libethcore/BlockHeader.h b/libethcore/BlockHeader.h index b51fe0bf329..8ae812dc54d 100644 --- a/libethcore/BlockHeader.h +++ b/libethcore/BlockHeader.h @@ -153,6 +153,7 @@ class BlockHeader h256 const& parentHash() const { return m_parentHash; } h256 const& sha3Uncles() const { return m_sha3Uncles; } + bool hasUncles() const { return m_sha3Uncles != EmptyListSHA3; } u256 const& timestamp() const { return m_timestamp; } Address const& author() const { return m_author; } h256 const& stateRoot() const { return m_stateRoot; } From ff3d51dafaba858a8b2ea6ce347fb85012ebf877 Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Mon, 27 Mar 2017 15:08:33 +0200 Subject: [PATCH 2/2] Unit tests for difficulty calculation --- test/unittests/libethashseal/EthashTest.cpp | 99 +++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 test/unittests/libethashseal/EthashTest.cpp diff --git a/test/unittests/libethashseal/EthashTest.cpp b/test/unittests/libethashseal/EthashTest.cpp new file mode 100644 index 00000000000..6abb71dd5cf --- /dev/null +++ b/test/unittests/libethashseal/EthashTest.cpp @@ -0,0 +1,99 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file ethash.cpp + * Ethash class testing. + */ + +#include +#include +#include + +using namespace std; +using namespace dev; +using namespace dev::eth; +using namespace dev::test; + +BOOST_FIXTURE_TEST_SUITE(EthashTests, TestOutputHelper) + +BOOST_AUTO_TEST_CASE(calculateDifficultyMetropolisWithoutUncles) +{ + ChainOperationParams params; + params.otherParams["metropolisForkBlock"] = "0x1000"; + + Ethash ethash; + ethash.setChainParams(params); + + BlockHeader parentHeader; + parentHeader.clear(); + parentHeader.setNumber(0x2000); + parentHeader.setTimestamp(100); + parentHeader.setDifficulty(1000000); + + BlockHeader header; + header.clear(); + header.setNumber(0x2001); + header.setTimestamp(130); + + BOOST_REQUIRE_EQUAL(ethash.calculateDifficulty(header, parentHeader), 999024); +} + +BOOST_AUTO_TEST_CASE(calculateDifficultyMetropolisWithUncles) +{ + ChainOperationParams params; + params.otherParams["metropolisForkBlock"] = "0x1000"; + + Ethash ethash; + ethash.setChainParams(params); + + BlockHeader parentHeader; + parentHeader.clear(); + parentHeader.setNumber(0x2000); + parentHeader.setTimestamp(100); + parentHeader.setDifficulty(1000000); + parentHeader.setSha3Uncles(h256("0x949d991d685738352398dff73219ab19c62c06e6f8ce899fbae755d5127ed1ef")); + + BlockHeader header; + header.clear(); + header.setNumber(0x2001); + header.setTimestamp(130); + + BOOST_REQUIRE_EQUAL(ethash.calculateDifficulty(header, parentHeader), 999512); +} + +BOOST_AUTO_TEST_CASE(calculateDifficultyMetropolisMaxAdjustment) +{ + ChainOperationParams params; + params.otherParams["metropolisForkBlock"] = "0x1000"; + + Ethash ethash; + ethash.setChainParams(params); + + BlockHeader parentHeader; + parentHeader.clear(); + parentHeader.setNumber(0x2000); + parentHeader.setTimestamp(100); + parentHeader.setDifficulty(1000000); + + BlockHeader header; + header.clear(); + header.setNumber(0x2001); + header.setTimestamp(1100); + + BOOST_REQUIRE_EQUAL(ethash.calculateDifficulty(header, parentHeader), 951688); +} + +BOOST_AUTO_TEST_SUITE_END()