Skip to content

Commit

Permalink
Cherry pick thanos (#1474)
Browse files Browse the repository at this point in the history
* [ECIP-1099] Implement ECIP 1099: Calibrate Epoch Duration (#1421)
(cherry picked from commit 787871a)
Signed-off-by: Danno Ferrin <danno.ferrin@gmail.com>

* rename genesis config option Ecip1099Block to ThanosBlock (#1462)
(cherry picked from commit 2d7cdf0)
Signed-off-by: Danno Ferrin <danno.ferrin@gmail.com>

Co-authored-by: Edward Mack <ed@edwardmack.com>
  • Loading branch information
shemnon and edwardmack committed Oct 19, 2020
1 parent d2cf70a commit 3ae79e7
Show file tree
Hide file tree
Showing 22 changed files with 271 additions and 39 deletions.
20 changes: 19 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
# Changelog

## Deprecated and Scheduled for removal in _Next_ Release

### --privacy-precompiled-address
Deprecated in 1.5.1
- CLI option `--privacy-precompiled-address` option removed. This address is now derived, based
on `--privacy-onchain-groups-enabled`. [\#1222](https://github.com/hyperledger/besu/pull/1222)

## 20.10 Breaking Changes

When upgrading to 20.10, ensure you've taken into account the following breaking changes.

## JSON-RPC HTTP Error Codes For Valid Calls
### JSON-RPC HTTP Error Codes For Valid Calls

Prior versions of Besu would set the HTTP Status 400 Bad Request for JSON-RPC requests that completed in an error, regardless of the kind of error. These responses could include a complete JSON-RPC response with an error field.

In Besu version 20.10, properly formatted requests that have valid parameters (count and content) will return a HTTP Status 200 OK, with an error field if an error occurred. For example, requesting an account that does not exist in the chain, or a block by hash that Besu does not have, will now return HTTP 200 OK responses. Unparsable requests, improperly formatted requests, or requests with invalid parameters will continue to return HTTP 400 Bad Request.

Users of Web3J should note that many calls will now return a result with the error field containing the message whereas before a call would throw an exception with the error message as the exception message.

## 20.10.0-RC2

### Additions and Improvements
* Added support for ECIP-1099 / Classic Thanos Fork: Calibrate Epoch Duration. [\#1421](https://github.com/hyperledger/besu/pull/1421) [\#1441](https://github.com/hyperledger/besu/pull/1441) [\#1462](https://github.com/hyperledger/besu/pull/1462)

## 20.10.0-RC1

### Release format
Expand All @@ -38,6 +50,12 @@ Hyperledger Besu is moving its versioning scheme to [CalVer](https://calver.org/
- [Privacy users with private transactions created using v1.3.4 or earlier](KNOWN_ISSUES.md#privacy-users-with-private-transactions-created-using-v134-or-earlier)
- [Changes not saved to database correctly causing inconsistent private states](KNOWN_ISSUES.md#Changes-not-saved-to-database-correctly-causing-inconsistent-private-states)


### Download link

https://dl.bintray.com/hyperledger-org/besu-repo/besu-20.10.0-RC1.zip
sha256sum: `ae8979e43a81a69d3dcf207b556275d94edbb67490747f0454269f87d38ee4fb`

## 1.5.5

### Additions and Improvements
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,18 @@
import org.hyperledger.besu.ethereum.eth.manager.EthProtocolManager;
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.mainnet.EthHash;
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderValidator;
import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;

import java.util.function.Function;

public class MainnetBesuControllerBuilder extends BesuControllerBuilder {

private Function<Long, Long> epochCalculator = EthHash::epoch;

@Override
protected MiningCoordinator createMiningCoordinator(
final ProtocolSchedule protocolSchedule,
Expand All @@ -49,7 +54,8 @@ protected MiningCoordinator createMiningCoordinator(
MainnetBlockHeaderValidator.MINIMUM_SECONDS_SINCE_PARENT,
MainnetBlockHeaderValidator.TIMESTAMP_TOLERANCE_S,
clock),
gasLimitCalculator);
gasLimitCalculator,
epochCalculator);

final EthHashMiningCoordinator miningCoordinator =
new EthHashMiningCoordinator(
Expand Down Expand Up @@ -85,4 +91,12 @@ protected ProtocolSchedule createProtocolSchedule() {
privacyParameters,
isRevertReasonEnabled);
}

@Override
protected void prepForBuild() {
genesisConfig
.getConfigOptions()
.getThanosBlockNumber()
.ifPresent(activationBlock -> epochCalculator = EthHash.ecip1099Epoch(activationBlock));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,16 @@ public interface GenesisConfigOptions {
*/
OptionalLong getPhoenixBlockNumber();

/**
* Block number to activate ECIP-1099 (Thanos) on Classic networks. Doubles the length of the
* Ethash epoch, with the impact being a reduced DAG size.
*
* @see <a
* href="https://ecips.ethereumclassic.org/ECIPs/ecip-1099">https://ecips.ethereumclassic.org/ECIPs/ecip-1099</a>
* @return block number of ECIP-1099 fork on Classic networks
*/
OptionalLong getThanosBlockNumber();

Optional<BigInteger> getChainId();

OptionalInt getContractSizeLimit();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions {
private static final String IBFT_LEGACY_CONFIG_KEY = "ibft";
private static final String IBFT2_CONFIG_KEY = "ibft2";
private static final String CLIQUE_CONFIG_KEY = "clique";

private static final String TRANSITIONS_CONFIG_KEY = "transitions";
private final ObjectNode configRoot;
private final Map<String, String> configOverrides = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
Expand Down Expand Up @@ -274,6 +275,11 @@ public OptionalLong getPhoenixBlockNumber() {
return getOptionalLong("phoenixblock");
}

@Override
public OptionalLong getThanosBlockNumber() {
return getOptionalLong("thanosblock");
}

@Override
public Optional<BigInteger> getChainId() {
return getOptionalBigInteger("chainid");
Expand Down Expand Up @@ -328,6 +334,7 @@ public Map<String, Object> asMap() {
getContractSizeLimit().ifPresent(l -> builder.put("contractSizeLimit", l));
getEvmStackSize().ifPresent(l -> builder.put("evmstacksize", l));
getEcip1017EraRounds().ifPresent(l -> builder.put("ecip1017EraRounds", l));
getThanosBlockNumber().ifPresent(l -> builder.put("thanosBlock", l));

if (isClique()) {
builder.put("clique", getCliqueConfigOptions().asMap());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions {
private final OptionalLong atlantisBlockNumber = OptionalLong.empty();
private final OptionalLong aghartaBlockNumber = OptionalLong.empty();
private final OptionalLong phoenixBlockNumber = OptionalLong.empty();
private final OptionalLong thanosBlockNumber = OptionalLong.empty();
private Optional<BigInteger> chainId = Optional.empty();
private OptionalInt contractSizeLimit = OptionalInt.empty();
private OptionalInt stackSizeLimit = OptionalInt.empty();
Expand Down Expand Up @@ -192,6 +193,11 @@ public OptionalLong getPhoenixBlockNumber() {
return phoenixBlockNumber;
}

@Override
public OptionalLong getThanosBlockNumber() {
return thanosBlockNumber;
}

@Override
public OptionalInt getContractSizeLimit() {
return contractSizeLimit;
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 @@ -10,6 +10,7 @@
"atlantisBlock": 8772000,
"aghartaBlock": 9573000,
"phoenixBlock": 10500839,
"thanosBlock": 11700000,
"ethash": {

}
Expand Down
1 change: 1 addition & 0 deletions config/src/main/resources/mordor.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"aghartaBlock": 301243,
"phoenixBlock": 999983,
"ecip1017EraRounds": 2000000,
"thanosBlock": 2520000,
"ethash": {}
},
"nonce": "0x0000000000000000",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,19 @@

public class EthHashMinerExecutor extends AbstractMinerExecutor<EthHashBlockMiner> {

private volatile Optional<Address> coinbase;
private boolean stratumMiningEnabled;
private final Iterable<Long> nonceGenerator;
protected volatile Optional<Address> coinbase;
protected boolean stratumMiningEnabled;
protected final Iterable<Long> nonceGenerator;
protected final Function<Long, Long> epochCalculator;

public EthHashMinerExecutor(
final ProtocolContext protocolContext,
final ProtocolSchedule protocolSchedule,
final PendingTransactions pendingTransactions,
final MiningParameters miningParams,
final AbstractBlockScheduler blockScheduler,
final GasLimitCalculator gasLimitCalculator) {
final GasLimitCalculator gasLimitCalculator,
final Function<Long, Long> epochCalculator) {
super(
protocolContext,
protocolSchedule,
Expand All @@ -51,6 +53,7 @@ public EthHashMinerExecutor(
gasLimitCalculator);
this.coinbase = miningParams.getCoinbase();
this.nonceGenerator = miningParams.getNonceGenerator().orElse(new RandomNonceGenerator());
this.epochCalculator = epochCalculator;
}

@Override
Expand All @@ -71,7 +74,11 @@ public EthHashBlockMiner createMiner(
final BlockHeader parentHeader) {
final EthHashSolver solver =
new EthHashSolver(
nonceGenerator, new EthHasher.Light(), stratumMiningEnabled, ethHashObservers);
nonceGenerator,
new EthHasher.Light(),
stratumMiningEnabled,
ethHashObservers,
epochCalculator);
final Function<BlockHeader, EthHashBlockCreator> blockCreator =
(header) ->
new EthHashBlockCreator(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.hyperledger.besu.ethereum.core.Wei;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.mainnet.EthHash;
import org.hyperledger.besu.ethereum.mainnet.EthHashSolver;
import org.hyperledger.besu.ethereum.mainnet.EthHasher;
import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder;
Expand Down Expand Up @@ -77,7 +78,11 @@ public void createMainnetBlock1() throws IOException {

final EthHashSolver solver =
new EthHashSolver(
Lists.newArrayList(BLOCK_1_NONCE), new EthHasher.Light(), false, Subscribers.none());
Lists.newArrayList(BLOCK_1_NONCE),
new EthHasher.Light(),
false,
Subscribers.none(),
EthHash::epoch);

final PendingTransactions pendingTransactions =
new PendingTransactions(
Expand Down Expand Up @@ -131,7 +136,11 @@ public void createMainnetBlock1_fixedDifficulty1() {

final EthHashSolver solver =
new EthHashSolver(
Lists.newArrayList(BLOCK_1_NONCE), new EthHasher.Light(), false, Subscribers.none());
Lists.newArrayList(BLOCK_1_NONCE),
new EthHasher.Light(),
false,
Subscribers.none(),
EthHash::epoch);

final PendingTransactions pendingTransactions =
new PendingTransactions(
Expand Down Expand Up @@ -180,7 +189,11 @@ public void rewardBeneficiary_zeroReward_skipZeroRewardsFalse() {

final EthHashSolver solver =
new EthHashSolver(
Lists.newArrayList(BLOCK_1_NONCE), new EthHasher.Light(), false, Subscribers.none());
Lists.newArrayList(BLOCK_1_NONCE),
new EthHasher.Light(),
false,
Subscribers.none(),
EthHash::epoch);

final PendingTransactions pendingTransactions =
new PendingTransactions(
Expand Down Expand Up @@ -245,7 +258,11 @@ public void rewardBeneficiary_zeroReward_skipZeroRewardsTrue() {

final EthHashSolver solver =
new EthHashSolver(
Lists.newArrayList(BLOCK_1_NONCE), new EthHasher.Light(), false, Subscribers.none());
Lists.newArrayList(BLOCK_1_NONCE),
new EthHasher.Light(),
false,
Subscribers.none(),
EthHash::epoch);

final PendingTransactions pendingTransactions =
new PendingTransactions(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.hyperledger.besu.ethereum.core.MiningParametersTestBuilder;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.mainnet.EthHash;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import org.hyperledger.besu.testutil.TestClock;
Expand Down Expand Up @@ -55,7 +56,8 @@ public void startingMiningWithoutCoinbaseThrowsException() {
pendingTransactions,
miningParameters,
new DefaultBlockScheduler(1, 10, TestClock.fixed()),
GasLimitCalculator.constant());
GasLimitCalculator.constant(),
EthHash::epoch);

assertThatExceptionOfType(CoinbaseNotSetException.class)
.isThrownBy(() -> executor.startAsyncMining(Subscribers.create(), Subscribers.none(), null))
Expand Down Expand Up @@ -84,7 +86,8 @@ public void settingCoinbaseToNullThrowsException() {
pendingTransactions,
miningParameters,
new DefaultBlockScheduler(1, 10, TestClock.fixed()),
GasLimitCalculator.constant());
GasLimitCalculator.constant(),
EthHash::epoch);

assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> executor.setCoinbase(null))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,27 @@ public static ProtocolSpecBuilder phoenixDefinition(
.name("Phoenix");
}

public static ProtocolSpecBuilder thanosDefinition(
final Optional<BigInteger> chainId,
final OptionalInt configContractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final OptionalLong ecip1017EraRounds) {
return phoenixDefinition(
chainId,
configContractSizeLimit,
configStackSizeLimit,
enableRevertReason,
ecip1017EraRounds)
.blockHeaderValidatorBuilder(
MainnetBlockHeaderValidator.createBlockHeaderValidator(
block -> EthHash.epoch(block, EthHash.EPOCH_LENGTH * 2)))
.ommerHeaderValidatorBuilder(
MainnetBlockHeaderValidator.createOmmerValidator(
block -> EthHash.epoch(block, EthHash.EPOCH_LENGTH * 2)))
.name("Thanos");
}

private static TransactionReceipt byzantiumTransactionReceiptFactory(
final TransactionProcessor.Result result, final WorldState worldState, final long gasUsed) {
return new TransactionReceipt(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.security.DigestException;
import java.security.MessageDigest;
import java.util.function.BiConsumer;
import java.util.function.Function;

import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
Expand Down Expand Up @@ -188,13 +189,47 @@ public static byte[] hashHeader(final SealableBlockHeader header) {
}

/**
* Calculates the EthHash Epoch for a given block number.
* Calculates the EthHash Epoch for a given block number with the default epoch length.
*
* @param block Block Number
* @return EthHash Epoch
*/
public static long epoch(final long block) {
return Long.divideUnsigned(block, EPOCH_LENGTH);
return epoch(block, EPOCH_LENGTH);
}

/**
* Calculates the EthHash Epoch for a given block number.
*
* @param block BLock Number
* @param epochLength The epoch length
* @return EthHash Epoch
*/
public static long epoch(final long block, final long epochLength) {
return Long.divideUnsigned(block, epochLength);
}

/**
* Returns a function that returns different epoch lengths on either side of activation block.
*
* @param activationBlock the block that the length changes
* @param oldLength the length prior to the activation block
* @param newLength the length on and after the activation block
* @return epoch length
*/
public static Function<Long, Long> changingEpoch(
final long activationBlock, final long oldLength, final long newLength) {
return block -> block < activationBlock ? epoch(block, oldLength) : epoch(block, newLength);
}

/**
* Returns a function that returns the ECIP-1099 epoch formula.
*
* @param activationBlock the block that the length changes
* @return epoch length
*/
public static Function<Long, Long> ecip1099Epoch(final long activationBlock) {
return changingEpoch(activationBlock, EPOCH_LENGTH, EPOCH_LENGTH * 2);
}

/**
Expand Down
Loading

0 comments on commit 3ae79e7

Please sign in to comment.