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

[PAN-2989] EIP-1884 - Repricing for trie-size-dependent opcodes #1795

Merged
merged 4 commits into from
Jul 30, 2019
Merged
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 @@ -98,6 +98,7 @@ public MessageFrame.Builder createMessageFrameBuilder() {
.address(messageFrame.getContractAddress())
.originator(messageFrame.getOriginatorAddress())
.contract(messageFrame.getRecipientAddress())
.contractBalance(messageFrame.getContractBalance())
.gasPrice(messageFrame.getGasPrice())
.inputData(messageFrame.getInputData())
.sender(messageFrame.getSenderAddress())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ public class IstanbulGasCalculator extends ConstantinopleFixGasCalculator {
private static final Gas TX_BASE_COST = Gas.of(21_000L);

private static final Gas SLOAD_GAS = Gas.of(800);
private static final Gas BALANCE_OPERATION_GAS_COST = Gas.of(700);
private static final Gas EXTCODE_HASH_COST = Gas.of(700);

private static final Gas SSTORE_SET_GAS = Gas.of(20_000);
private static final Gas SSTORE_RESET_GAS = Gas.of(5_000);
private static final Gas SSTORE_CLEARS_SCHEDULE = Gas.of(15_000);
Expand Down Expand Up @@ -114,4 +117,22 @@ public Gas calculateStorageRefundAmount(
}
}
}

@Override
// As per https://eips.ethereum.org/EIPS/eip-1884
public Gas getSloadOperationGasCost() {
return SLOAD_GAS;
}

@Override
// As per https://eips.ethereum.org/EIPS/eip-1884
public Gas getBalanceOperationGasCost() {
return BALANCE_OPERATION_GAS_COST;
}

@Override
// As per https://eips.ethereum.org/EIPS/eip-1884
public Gas extCodeHashOperationGasCost() {
return EXTCODE_HASH_COST;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
import tech.pegasys.pantheon.ethereum.vm.operations.SModOperation;
import tech.pegasys.pantheon.ethereum.vm.operations.SStoreOperation;
import tech.pegasys.pantheon.ethereum.vm.operations.SarOperation;
import tech.pegasys.pantheon.ethereum.vm.operations.SelfBalanceOperation;
import tech.pegasys.pantheon.ethereum.vm.operations.SelfDestructOperation;
import tech.pegasys.pantheon.ethereum.vm.operations.Sha3Operation;
import tech.pegasys.pantheon.ethereum.vm.operations.ShlOperation;
Expand Down Expand Up @@ -266,12 +267,10 @@ private static void registerIstanbulOpcodes(
final int accountVersion,
final BigInteger chainId) {
registerConstantinopleOpcodes(registry, gasCalculator, accountVersion);
registry.put(
new SStoreOperation(gasCalculator, SStoreOperation.EIP_1706_MINIMUM),
Account.DEFAULT_VERSION);
registry.put(
new ChainIdOperation(gasCalculator, Bytes32.leftPad(BytesValue.of(chainId.toByteArray()))),
Account.DEFAULT_VERSION);
registry.put(new SelfBalanceOperation(gasCalculator), Account.DEFAULT_VERSION);
registry.put(
new SStoreOperation(gasCalculator, SStoreOperation.EIP_1706_MINIMUM),
Account.DEFAULT_VERSION);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ public Result processTransaction(
.address(contractAddress)
.originator(senderAddress)
.contract(contractAddress)
.contractBalance(sender.getBalance())
.contractAccountVersion(createContractAccountVersion)
.gasPrice(transaction.getGasPrice())
.inputData(BytesValue.EMPTY)
Expand Down Expand Up @@ -264,6 +265,7 @@ public Result processTransaction(
.address(to)
.originator(senderAddress)
.contract(to)
.contractBalance(contract != null ? contract.getBalance() : Wei.ZERO)
.contractAccountVersion(
contract != null ? contract.getVersion() : Account.DEFAULT_VERSION)
.gasPrice(transaction.getGasPrice())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ public Result processTransaction(
.address(privateContractAddress)
.originator(senderAddress)
.contract(privateContractAddress)
.contractBalance(Wei.ZERO)
.contractAccountVersion(createContractAccountVersion)
.initialGas(Gas.MAX_VALUE)
.gasPrice(transaction.getGasPrice())
Expand Down Expand Up @@ -259,6 +260,7 @@ public Result processTransaction(
.address(to)
.originator(senderAddress)
.contract(to)
.contractBalance(contract != null ? contract.getBalance() : Wei.ZERO)
.contractAccountVersion(
contract != null ? contract.getVersion() : Account.DEFAULT_VERSION)
.initialGas(Gas.MAX_VALUE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ public void execute(final MessageFrame frame) {
.address(address(frame))
.originator(frame.getOriginatorAddress())
.contract(to)
.contractBalance(contract != null ? contract.getBalance() : Wei.ZERO)
.contractAccountVersion(
contract != null ? contract.getVersion() : Account.DEFAULT_VERSION)
.gasPrice(frame.getGasPrice())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ public enum Type {
private final Address recipient;
private final Address originator;
private final Address contract;
private final Wei contractBalance;
private final int contractAccountVersion;
private final Wei gasPrice;
private final BytesValue inputData;
Expand Down Expand Up @@ -240,6 +241,7 @@ private MessageFrame(
final Address recipient,
final Address originator,
final Address contract,
final Wei contractBalance,
final int contractAccountVersion,
final Wei gasPrice,
final BytesValue inputData,
Expand Down Expand Up @@ -274,6 +276,7 @@ private MessageFrame(
this.recipient = recipient;
this.originator = originator;
this.contract = contract;
this.contractBalance = contractBalance;
this.contractAccountVersion = contractAccountVersion;
this.gasPrice = gasPrice;
this.inputData = inputData;
Expand Down Expand Up @@ -753,6 +756,15 @@ public Address getContractAddress() {
return contract;
}

/**
* Returns the balance of the contract currently executing.
*
* @return the balance of the contract currently executing
*/
public Wei getContractBalance() {
return contractBalance;
}

/**
* Returns the current gas price.
*
Expand Down Expand Up @@ -864,6 +876,7 @@ public static class Builder {
private Address address;
private Address originator;
private Address contract;
private Wei contractBalance;
private int contractAccountVersion = -1;
private Wei gasPrice;
private BytesValue inputData;
Expand Down Expand Up @@ -921,6 +934,11 @@ public Builder contract(final Address contract) {
return this;
}

public Builder contractBalance(final Wei contractBalance) {
this.contractBalance = contractBalance;
return this;
}

public Builder contractAccountVersion(final int contractAccountVersion) {
checkArgument(contractAccountVersion >= 0, "Contract account version cannot be negative");
this.contractAccountVersion = contractAccountVersion;
Expand Down Expand Up @@ -1011,6 +1029,7 @@ private void validate() {
checkState(address != null, "Missing message frame recipient");
checkState(originator != null, "Missing message frame originator");
checkState(contract != null, "Missing message frame contract");
checkState(contractBalance != null, "Missing message frame contractBalance");
checkState(gasPrice != null, "Missing message frame getGasRemaining price");
checkState(inputData != null, "Missing message frame input data");
checkState(sender != null, "Missing message frame sender");
Expand Down Expand Up @@ -1038,6 +1057,7 @@ public MessageFrame build() {
address,
originator,
contract,
contractBalance,
contractAccountVersion,
gasPrice,
inputData,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ private void spawnChildMessage(final MessageFrame frame) {
.address(contractAddress)
.originator(frame.getOriginatorAddress())
.contract(contractAddress)
.contractBalance(account.getBalance())
.contractAccountVersion(frame.getContractAccountVersion())
.gasPrice(frame.getGasPrice())
.inputData(BytesValue.EMPTY)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2018 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.ethereum.vm.operations;

import tech.pegasys.pantheon.ethereum.core.Gas;
import tech.pegasys.pantheon.ethereum.vm.AbstractOperation;
import tech.pegasys.pantheon.ethereum.vm.GasCalculator;
import tech.pegasys.pantheon.ethereum.vm.MessageFrame;

public class SelfBalanceOperation extends AbstractOperation {

public SelfBalanceOperation(final GasCalculator gasCalculator) {
super(0x47, "SELFBALANCE", 0, 1, false, 1, gasCalculator);
}

@Override
public Gas cost(final MessageFrame frame) {
return gasCalculator().getLowTierGasCost();
}

@Override
public void execute(final MessageFrame frame) {
frame.pushStackItem(frame.getContractBalance().getBytes());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public class MessageFrameTestFixture {
private Address sender = DEFAUT_ADDRESS;
private Address originator = DEFAUT_ADDRESS;
private Address contract = DEFAUT_ADDRESS;
private Wei contractBalance = Wei.of(1);
private int contractAccountVersion = Account.DEFAULT_VERSION;
private Wei gasPrice = Wei.ZERO;
private Wei value = Wei.ZERO;
Expand Down Expand Up @@ -109,6 +110,11 @@ public MessageFrameTestFixture contract(final Address contract) {
return this;
}

public MessageFrameTestFixture contractBalance(final Wei contractBalance) {
this.contractBalance = contractBalance;
return this;
}

public MessageFrameTestFixture contractAccountVersion(final int contractAccountVersion) {
this.contractAccountVersion = contractAccountVersion;
return this;
Expand Down Expand Up @@ -173,6 +179,7 @@ public MessageFrame build() {
.value(value)
.apparentValue(value)
.contract(contract)
.contractBalance(contractBalance)
.contractAccountVersion(contractAccountVersion)
.code(code)
.blockHeader(blockHeader)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public class EnvironmentInformation {

private final Address accountAddress;

private final Wei accountBalance;

private BlockHeader blockHeader;

private final Address callerAddress;
Expand Down Expand Up @@ -69,6 +71,7 @@ public class EnvironmentInformation {
@JsonCreator
public EnvironmentInformation(
@JsonProperty("address") final String account,
@JsonProperty("balance") final String balance,
Copy link
Contributor

Choose a reason for hiding this comment

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

Are there new reference tests that use this? Or is this speculative?

@JsonProperty("caller") final String caller,
@JsonProperty("code") final CodeMock code,
@JsonProperty("data") final String data,
Expand All @@ -81,6 +84,7 @@ public EnvironmentInformation(
code,
0,
account == null ? null : Address.fromHexString(account),
balance == null ? Wei.ZERO : Wei.fromHexString(balance),
caller == null ? null : Address.fromHexString(caller),
origin == null ? null : Address.fromHexString(origin),
data == null ? null : BytesValue.fromHexString(data),
Expand All @@ -94,6 +98,7 @@ private EnvironmentInformation(
final Code code,
final int depth,
final Address accountAddress,
final Wei accountBalance,
final Address callerAddress,
final Address originAddress,
final BytesValue data,
Expand All @@ -104,6 +109,7 @@ private EnvironmentInformation(
this.code = code;
this.depth = depth;
this.accountAddress = accountAddress;
this.accountBalance = accountBalance;
this.callerAddress = callerAddress;
this.originAddress = originAddress;
this.data = data;
Expand Down Expand Up @@ -132,6 +138,11 @@ public Address getAccountAddress() {
return accountAddress;
}

/** @return The balance of the currently executing account */
public Wei getAccountBalance() {
return accountBalance;
}

/** @return Address of the caller. */
public Address getCallerAddress() {
return callerAddress;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ protected void runTest() {
.worldState(worldState.updater())
.initialGas(spec.getExec().getGas())
.contract(execEnv.getAccountAddress())
.contractBalance(execEnv.getAccountBalance())
.address(execEnv.getAccountAddress())
.originator(execEnv.getOriginAddress())
.gasPrice(execEnv.getGasPrice())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import tech.pegasys.pantheon.ethereum.core.Wei;
import tech.pegasys.pantheon.ethereum.core.WorldUpdater;
import tech.pegasys.pantheon.ethereum.mainnet.ConstantinopleGasCalculator;
import tech.pegasys.pantheon.ethereum.mainnet.IstanbulGasCalculator;
import tech.pegasys.pantheon.ethereum.vm.MessageFrame;
import tech.pegasys.pantheon.ethereum.vm.Words;
import tech.pegasys.pantheon.ethereum.worldstate.WorldStateArchive;
Expand All @@ -49,12 +50,20 @@ public class ExtCodeHashOperationTest {

private final ExtCodeHashOperation operation =
new ExtCodeHashOperation(new ConstantinopleGasCalculator());
private final ExtCodeHashOperation operationIstanbul =
new ExtCodeHashOperation(new IstanbulGasCalculator());

@Test
public void shouldCharge400Gas() {
assertThat(operation.cost(createMessageFrame(REQUESTED_ADDRESS))).isEqualTo(Gas.of(400));
}

@Test
public void istanbulShouldCharge700Gas() {
assertThat(operationIstanbul.cost(createMessageFrame(REQUESTED_ADDRESS)))
.isEqualTo(Gas.of(700));
}

@Test
public void shouldReturnZeroWhenAccountDoesNotExist() {
final Bytes32 result = executeOperation(REQUESTED_ADDRESS);
Expand Down