Skip to content
This repository has been archived by the owner on Sep 26, 2019. It is now read-only.

[PAN-3023] Add command line option for target gas limit #1917

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import tech.pegasys.pantheon.Runner;
import tech.pegasys.pantheon.RunnerBuilder;
import tech.pegasys.pantheon.cli.config.EthNetworkConfig;
import tech.pegasys.pantheon.controller.GasLimitCalculator;
import tech.pegasys.pantheon.controller.KeyPairUtil;
import tech.pegasys.pantheon.controller.PantheonController;
import tech.pegasys.pantheon.controller.PantheonControllerBuilder;
Expand Down Expand Up @@ -146,6 +147,7 @@ public void startNode(final PantheonNode node) {
.clock(Clock.systemUTC())
.isRevertReasonEnabled(node.isRevertReasonEnabled())
.storageProvider(storageProvider)
.targetGasLimit(GasLimitCalculator.DEFAULT)
.build();
} catch (final IOException e) {
throw new RuntimeException("Error building PantheonController", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,16 @@ public CliqueMinerExecutor(
final KeyPair nodeKeys,
final MiningParameters miningParams,
final AbstractBlockScheduler blockScheduler,
final EpochManager epochManager) {
final EpochManager epochManager,
final Function<Long, Long> gasLimitCalculator) {
super(
protocolContext,
executorService,
protocolSchedule,
pendingTransactions,
miningParams,
blockScheduler);
blockScheduler,
gasLimitCalculator);
this.nodeKeys = nodeKeys;
this.localAddress = Util.publicKeyToAddress(nodeKeys.getPublicKey());
this.epochManager = epochManager;
Expand Down Expand Up @@ -89,7 +91,7 @@ private CliqueBlockMiner createMiner(
pendingTransactions,
protocolContext,
protocolSchedule,
(gasLimit) -> gasLimit,
gasLimitCalculator,
nodeKeys,
minTransactionGasPrice,
header,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import tech.pegasys.pantheon.util.bytes.BytesValue;

import java.util.List;
import java.util.function.Function;

import com.google.common.collect.Lists;
import org.junit.Before;
Expand Down Expand Up @@ -121,7 +122,7 @@ public void proposerAddressCanBeExtractFromAConstructedBlock() {
metricsSystem),
protocolContext,
protocolSchedule,
gasLimit -> gasLimit,
Function.identity(),
proposerKeyPair,
Wei.ZERO,
blockchain.getChainHeadHeader(),
Expand Down Expand Up @@ -152,7 +153,7 @@ public void insertsValidVoteIntoConstructedBlock() {
metricsSystem),
protocolContext,
protocolSchedule,
gasLimit -> gasLimit,
Function.identity(),
proposerKeyPair,
Wei.ZERO,
blockchain.getChainHeadHeader(),
Expand Down Expand Up @@ -182,7 +183,7 @@ public void insertsNoVoteWhenAuthInValidators() {
metricsSystem),
protocolContext,
protocolSchedule,
gasLimit -> gasLimit,
Function.identity(),
proposerKeyPair,
Wei.ZERO,
blockchain.getChainHeadHeader(),
Expand Down Expand Up @@ -215,7 +216,7 @@ public void insertsNoVoteWhenAtEpoch() {
metricsSystem),
protocolContext,
protocolSchedule,
gasLimit -> gasLimit,
Function.identity(),
proposerKeyPair,
Wei.ZERO,
blockchain.getChainHeadHeader(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.function.Function;

import com.google.common.collect.Lists;
import org.junit.Before;
Expand Down Expand Up @@ -98,7 +99,8 @@ public void extraDataCreatedOnEpochBlocksContainsValidators() {
proposerKeyPair,
new MiningParameters(AddressHelpers.ofValue(1), Wei.ZERO, vanityData, false),
mock(CliqueBlockScheduler.class),
new EpochManager(EPOCH_LENGTH));
new EpochManager(EPOCH_LENGTH),
Function.identity());

// NOTE: Passing in the *parent* block, so must be 1 less than EPOCH
final BlockHeader header = blockHeaderBuilder.number(EPOCH_LENGTH - 1).buildHeader();
Expand Down Expand Up @@ -135,7 +137,8 @@ public void extraDataForNonEpochBlocksDoesNotContainValidaors() {
proposerKeyPair,
new MiningParameters(AddressHelpers.ofValue(1), Wei.ZERO, vanityData, false),
mock(CliqueBlockScheduler.class),
new EpochManager(EPOCH_LENGTH));
new EpochManager(EPOCH_LENGTH),
Function.identity());

// Parent block was epoch, so the next block should contain no validators.
final BlockHeader header = blockHeaderBuilder.number(EPOCH_LENGTH).buildHeader();
Expand Down Expand Up @@ -172,7 +175,8 @@ public void shouldUseLatestVanityData() {
proposerKeyPair,
new MiningParameters(AddressHelpers.ofValue(1), Wei.ZERO, initialVanityData, false),
mock(CliqueBlockScheduler.class),
new EpochManager(EPOCH_LENGTH));
new EpochManager(EPOCH_LENGTH),
Function.identity());

executor.setExtraData(modifiedVanityData);
final BytesValue extraDataBytes = executor.calculateExtraData(blockHeaderBuilder.buildHeader());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.function.Function;
import java.util.stream.Collectors;

import com.google.common.collect.Iterables;
Expand Down Expand Up @@ -290,7 +291,7 @@ private static ControllerAndState createControllerAndFinalState(

final IbftBlockCreatorFactory blockCreatorFactory =
new IbftBlockCreatorFactory(
(gasLimit) -> gasLimit,
Function.identity(),
pendingTransactions, // changed from IbftPantheonController
protocolContext,
protocolSchedule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.function.Function;

public abstract class AbstractMinerExecutor<
C, M extends BlockMiner<C, ? extends AbstractBlockCreator<C>>> {
Expand All @@ -34,6 +35,7 @@ public abstract class AbstractMinerExecutor<
protected final ProtocolSchedule<C> protocolSchedule;
protected final PendingTransactions pendingTransactions;
protected final AbstractBlockScheduler blockScheduler;
protected final Function<Long, Long> gasLimitCalculator;

protected volatile BytesValue extraData;
protected volatile Wei minTransactionGasPrice;
Expand All @@ -44,14 +46,16 @@ public AbstractMinerExecutor(
final ProtocolSchedule<C> protocolSchedule,
final PendingTransactions pendingTransactions,
final MiningParameters miningParams,
final AbstractBlockScheduler blockScheduler) {
final AbstractBlockScheduler blockScheduler,
final Function<Long, Long> gasLimitCalculator) {
this.protocolContext = protocolContext;
this.executorService = executorService;
this.protocolSchedule = protocolSchedule;
this.pendingTransactions = pendingTransactions;
this.extraData = miningParams.getExtraData();
this.minTransactionGasPrice = miningParams.getMinTransactionGasPrice();
this.blockScheduler = blockScheduler;
this.gasLimitCalculator = gasLimitCalculator;
}

public abstract M startAsyncMining(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,16 @@ public EthHashMinerExecutor(
final ProtocolSchedule<Void> protocolSchedule,
final PendingTransactions pendingTransactions,
final MiningParameters miningParams,
final AbstractBlockScheduler blockScheduler) {
final AbstractBlockScheduler blockScheduler,
final Function<Long, Long> gasLimitCalculator) {
super(
protocolContext,
executorService,
protocolSchedule,
pendingTransactions,
miningParams,
blockScheduler);
blockScheduler,
gasLimitCalculator);
this.coinbase = miningParams.getCoinbase();
}

Expand Down Expand Up @@ -77,7 +79,7 @@ private EthHashBlockMiner createMiner(
pendingTransactions,
protocolContext,
protocolSchedule,
(gasLimit) -> gasLimit,
gasLimitCalculator,
solver,
minTransactionGasPrice,
parentHeader);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import tech.pegasys.pantheon.util.Subscribers;

import java.util.concurrent.Executors;
import java.util.function.Function;

import org.junit.Test;

Expand All @@ -49,7 +50,8 @@ public void startingMiningWithoutCoinbaseThrowsException() {
null,
pendingTransactions,
miningParameters,
new DefaultBlockScheduler(1, 10, TestClock.fixed()));
new DefaultBlockScheduler(1, 10, TestClock.fixed()),
Function.identity());

assertThatExceptionOfType(CoinbaseNotSetException.class)
.isThrownBy(() -> executor.startAsyncMining(Subscribers.create(), null))
Expand All @@ -74,7 +76,8 @@ public void settingCoinbaseToNullThrowsException() {
null,
pendingTransactions,
miningParameters,
new DefaultBlockScheduler(1, 10, TestClock.fixed()));
new DefaultBlockScheduler(1, 10, TestClock.fixed()),
Function.identity());

assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> executor.setCoinbase(null))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,12 @@ void setBannedNodeIds(final List<String> values) {
"The name of a file containing the private key used to sign privacy marker transactions. If unset, each will be signed with a random key.")
private final Path privacyMarkerTransactionSigningKeyPath = null;

@Option(
names = {"--target-gas-limit"},
description =
"Sets target gas limit per block. If set each blocks gas limit will approach this setting over time if the current gas limit is different.")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MadelineMurray for help description text review

private final Long targetGasLimit = null;

@Option(
names = {"--tx-pool-max-size"},
paramLabel = MANDATORY_INTEGER_FORMAT_HELP,
Expand Down Expand Up @@ -1011,7 +1017,8 @@ public PantheonControllerBuilder<?> getControllerBuilder() {
.storageProvider(keyStorageProvider(keyValueStorageName))
.isPruningEnabled(isPruningEnabled)
.pruningConfiguration(buildPruningConfiguration())
.genesisConfigOverrides(genesisConfigOverrides);
.genesisConfigOverrides(genesisConfigOverrides)
.targetGasLimit(targetGasLimit);
} catch (final IOException e) {
throw new ExecutionException(this.commandLine, "Invalid path", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ protected MiningCoordinator createMiningCoordinator(
protocolContext.getConsensusState().getVoteTallyCache(),
localAddress,
secondsBetweenBlocks),
epochManager);
epochManager,
gasLimitCalculator);
final CliqueMiningCoordinator miningCoordinator =
new CliqueMiningCoordinator(
protocolContext.getBlockchain(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright 2019 ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package tech.pegasys.pantheon.controller;

import java.util.function.Function;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class GasLimitCalculator implements Function<Long, Long> {
private static final Logger LOG = LogManager.getLogger();
public static final long ADJUSTMENT_FACTOR = 1024L;
public static final Long DEFAULT = null;
private final long targetGasLimit;

public GasLimitCalculator(final Long targetGasLimit) {
this.targetGasLimit = targetGasLimit == null ? 0L : targetGasLimit;
}

@Override
public Long apply(final Long gasLimit) {
long newGasLimit;

if (targetGasLimit > gasLimit) {
newGasLimit = Math.min(targetGasLimit, gasLimit + ADJUSTMENT_FACTOR);
} else if (targetGasLimit < gasLimit) {
newGasLimit = Math.max(targetGasLimit, gasLimit - ADJUSTMENT_FACTOR);
} else {
return gasLimit;
}

LOG.debug("Adjusting block gas limit from {} to {}", gasLimit, newGasLimit);

return newGasLimit;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ protected MiningCoordinator createMiningCoordinator(

final IbftBlockCreatorFactory blockCreatorFactory =
new IbftBlockCreatorFactory(
(gasLimit) -> gasLimit,
gasLimitCalculator,
transactionPool.getPendingTransactions(),
protocolContext,
protocolSchedule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ protected MiningCoordinator createMiningCoordinator(
new DefaultBlockScheduler(
MainnetBlockHeaderValidator.MINIMUM_SECONDS_SINCE_PARENT,
MainnetBlockHeaderValidator.TIMESTAMP_TOLERANCE_S,
clock));
clock),
gasLimitCalculator);

final EthHashMiningCoordinator miningCoordinator =
new EthHashMiningCoordinator(protocolContext.getBlockchain(), executor, syncState);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ public abstract class PantheonControllerBuilder<C> {
protected Clock clock;
protected KeyPair nodeKeys;
protected boolean isRevertReasonEnabled;
protected GasLimitCalculator gasLimitCalculator;
private StorageProvider storageProvider;
private final List<Runnable> shutdownActions = new ArrayList<>();
private boolean isPruningEnabled;
Expand Down Expand Up @@ -180,6 +181,11 @@ public PantheonControllerBuilder<C> genesisConfigOverrides(
return this;
}

public PantheonControllerBuilder<C> targetGasLimit(final Long targetGasLimit) {
this.gasLimitCalculator = new GasLimitCalculator(targetGasLimit);
return this;
}

public PantheonController<C> build() {
checkNotNull(genesisConfig, "Missing genesis config");
checkNotNull(syncConfig, "Missing sync config");
Expand All @@ -193,6 +199,7 @@ public PantheonController<C> build() {
checkNotNull(transactionPoolConfiguration, "Missing transaction pool configuration");
checkNotNull(nodeKeys, "Missing node keys");
checkNotNull(storageProvider, "Must supply a storage provider");
checkNotNull(gasLimitCalculator, "Missing gas limit calculator");

prepForBuild();

Expand Down
2 changes: 2 additions & 0 deletions pantheon/src/test/java/tech/pegasys/pantheon/PrivacyTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import static org.assertj.core.api.Assertions.assertThat;

import tech.pegasys.pantheon.config.GenesisConfigFile;
import tech.pegasys.pantheon.controller.GasLimitCalculator;
import tech.pegasys.pantheon.controller.PantheonController;
import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair;
import tech.pegasys.pantheon.ethereum.core.Account;
Expand Down Expand Up @@ -77,6 +78,7 @@ public void privacyPrecompiled() throws IOException {
.clock(TestClock.fixed())
.privacyParameters(privacyParameters)
.transactionPoolConfiguration(TransactionPoolConfiguration.builder().build())
.targetGasLimit(GasLimitCalculator.DEFAULT)
.build();

final Address privacyContractAddress = Address.privacyPrecompiled(ADDRESS);
Expand Down
Loading