Skip to content

Commit

Permalink
Merge branch 'main' into prague/eip2537
Browse files Browse the repository at this point in the history
  • Loading branch information
shemnon authored May 7, 2024
2 parents 84e7923 + a4b835d commit 1c7fe5a
Show file tree
Hide file tree
Showing 18 changed files with 755 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public class TomlConfigurationDefaultProvider implements IDefaultValueProvider {
private final CommandLine commandLine;
private final InputStream configurationInputStream;
private TomlParseResult result;
private boolean isUnknownOptionsChecked;

/**
* Instantiates a new Toml config file default value provider.
Expand Down Expand Up @@ -230,6 +231,11 @@ private void checkConfigurationValidity() {
throw new ParameterException(
commandLine,
String.format("Unable to read TOML configuration file %s", configurationInputStream));

if (!isUnknownOptionsChecked && !commandLine.isUnmatchedArgumentsAllowed()) {
checkUnknownOptions(result);
isUnknownOptionsChecked = true;
}
}

/** Load configuration from file. */
Expand All @@ -249,8 +255,6 @@ public void loadConfigurationFromFile() {
commandLine, String.format("Invalid TOML configuration: %s", errors));
}

checkUnknownOptions(result);

this.result = result;

} catch (final IOException e) {
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -1036,7 +1036,7 @@ distributions {
from("build/reports/license/license-dependency.html") { into "." }
from("./docs/GettingStartedBinaries.md") { into "." }
from("./docs/DocsArchive0.8.0.html") { into "." }
from("build/besu.autocomplete.sh") { into "." }
from(autocomplete) { into "." }
}
}
}
Expand Down
1 change: 1 addition & 0 deletions datatypes/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ jar {

dependencies {
compileOnly 'com.fasterxml.jackson.core:jackson-databind'
compileOnly 'io.vertx:vertx-core'

implementation project(':crypto:algorithms')
implementation project(':ethereum:rlp')
Expand Down
1 change: 1 addition & 0 deletions evm/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ dependencies {
implementation 'tech.pegasys:jc-kzg-4844'

compileOnly 'com.fasterxml.jackson.core:jackson-databind'
compileOnly 'io.vertx:vertx-core'

testImplementation 'com.fasterxml.jackson.core:jackson-databind'
testImplementation 'info.picocli:picocli'
Expand Down
6 changes: 6 additions & 0 deletions evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
import org.hyperledger.besu.evm.operation.AddOperation;
import org.hyperledger.besu.evm.operation.AddressOperation;
import org.hyperledger.besu.evm.operation.AndOperation;
import org.hyperledger.besu.evm.operation.AuthCallOperation;
import org.hyperledger.besu.evm.operation.AuthOperation;
import org.hyperledger.besu.evm.operation.BalanceOperation;
import org.hyperledger.besu.evm.operation.BaseFeeOperation;
import org.hyperledger.besu.evm.operation.BlobBaseFeeOperation;
Expand Down Expand Up @@ -948,6 +950,10 @@ public static void registerPragueOperations(
final GasCalculator gasCalculator,
final BigInteger chainID) {
registerCancunOperations(registry, gasCalculator, chainID);

// EIP-3074 AUTH and AUTHCALL
registry.put(new AuthOperation(gasCalculator));
registry.put(new AuthCallOperation(gasCalculator));
}

/**
Expand Down
21 changes: 21 additions & 0 deletions evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,9 @@ public enum Type {
/** The mark of the undoable collections at the creation of this message frame */
private final long undoMark;

/** mutated by AUTH operation */
private Address authorizedBy = null;

/**
* Builder builder.
*
Expand Down Expand Up @@ -1371,6 +1374,24 @@ public Optional<List<VersionedHash>> getVersionedHashes() {
return txValues.versionedHashes();
}

/**
* Accessor for address that authorized future AUTHCALLs.
*
* @return the revert reason
*/
public Address getAuthorizedBy() {
return authorizedBy;
}

/**
* Mutator for address that authorizes future AUTHCALLs, set by AUTH opcode
*
* @param authorizedBy the address that authorizes future AUTHCALLs
*/
public void setAuthorizedBy(final Address authorizedBy) {
this.authorizedBy = authorizedBy;
}

/** Reset. */
public void reset() {
maybeUpdatedMemory = Optional.empty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,35 @@ long callOperationGasCost(
Address contract,
boolean accountIsWarm);

/**
* Returns the gas cost for AUTHCALL.
*
* @param frame The current frame
* @param stipend The gas stipend being provided by the CALL caller
* @param inputDataOffset The offset in memory to retrieve the CALL input data
* @param inputDataLength The CALL input data length
* @param outputDataOffset The offset in memory to place the CALL output data
* @param outputDataLength The CALL output data length
* @param transferValue The wei being transferred
* @param invoker The contract calling out on behalf of the authority
* @param invokee The address of the recipient (never null)
* @param accountIsWarm The address of the contract is "warm" as per EIP-2929
* @return The gas cost for the CALL operation
*/
default long authCallOperationGasCost(
final MessageFrame frame,
final long stipend,
final long inputDataOffset,
final long inputDataLength,
final long outputDataOffset,
final long outputDataLength,
final Wei transferValue,
final Account invoker,
final Address invokee,
final boolean accountIsWarm) {
return 0L;
}

/**
* Gets additional call stipend.
*
Expand Down Expand Up @@ -617,4 +646,18 @@ default long computeExcessBlobGas(final long parentExcessBlobGas, final int newB
default long computeExcessBlobGas(final long parentExcessBlobGas, final long blobGasUsed) {
return 0L;
}

/**
* Returns the gas cost of validating an auth commitment for an AUTHCALL
*
* @param frame the current frame, with memory to be read from
* @param offset start of memory read
* @param length amount of memory read
* @param authority address to check for warmup
* @return total gas cost for the operation
*/
default long authOperationGasCost(
final MessageFrame frame, final long offset, final long length, final Address authority) {
return 0L;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@

import static org.hyperledger.besu.datatypes.Address.KZG_POINT_EVAL;

import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.evm.account.Account;
import org.hyperledger.besu.evm.frame.MessageFrame;

/**
* Gas Calculator for Prague
*
Expand All @@ -27,6 +32,8 @@
* </UL>
*/
public class PragueGasCalculator extends CancunGasCalculator {
private final int AUTH_OP_FIXED_FEE = 3100;
private final long AUTH_CALL_VALUE_TRANSFER_GAS_COST = 6700;

/** Instantiates a new Prague Gas Calculator. */
public PragueGasCalculator() {
Expand All @@ -41,4 +48,55 @@ public PragueGasCalculator() {
protected PragueGasCalculator(final int maxPrecompile) {
super(maxPrecompile);
}

@Override
public long authOperationGasCost(
final MessageFrame frame, final long offset, final long length, final Address authority) {
final long memoryExpansionGasCost = memoryExpansionGasCost(frame, offset, length);
final long accessFee = frame.isAddressWarm(authority) ? 100 : 2600;
final long gasCost = AUTH_OP_FIXED_FEE + memoryExpansionGasCost + accessFee;
return gasCost;
}

/**
* Returns the gas cost to call another contract on behalf of an authority
*
* @return the gas cost to call another contract on behalf of an authority
*/
@Override
public long authCallOperationGasCost(
final MessageFrame frame,
final long stipend,
final long inputDataOffset,
final long inputDataLength,
final long outputDataOffset,
final long outputDataLength,
final Wei transferValue,
final Account invoker,
final Address invokee,
final boolean accountIsWarm) {

final long inputDataMemoryExpansionCost =
memoryExpansionGasCost(frame, inputDataOffset, inputDataLength);
final long outputDataMemoryExpansionCost =
memoryExpansionGasCost(frame, outputDataOffset, outputDataLength);
final long memoryExpansionCost =
Math.max(inputDataMemoryExpansionCost, outputDataMemoryExpansionCost);

final long staticGasCost = getWarmStorageReadCost();

long dynamicGasCost = accountIsWarm ? 0 : getColdAccountAccessCost() - getWarmStorageReadCost();

if (!transferValue.isZero()) {
dynamicGasCost += AUTH_CALL_VALUE_TRANSFER_GAS_COST;
}

if ((invoker == null || invoker.isEmpty()) && !transferValue.isZero()) {
dynamicGasCost += newAccountGasCost();
}

long cost = staticGasCost + memoryExpansionCost + dynamicGasCost;

return cost;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Copyright contributors to Hyperledger Besu.
*
* 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.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.evm.operation;

import static org.hyperledger.besu.evm.internal.Words.clampedToLong;

import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.evm.EVM;
import org.hyperledger.besu.evm.frame.ExceptionalHaltReason;
import org.hyperledger.besu.evm.frame.MessageFrame;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.evm.internal.Words;

import org.apache.tuweni.bytes.Bytes32;

/** Introduced via EIP-3074 to call another contract with a different authorization context. */
public class AuthCallOperation extends AbstractCallOperation {

/**
* Instantiates a new AuthCallOperation.
*
* @param gasCalculator a Prague or later gas calculator
*/
public AuthCallOperation(final GasCalculator gasCalculator) {
super(0xF7, "AUTHCALL", 7, 1, gasCalculator);
}

@Override
protected Address to(final MessageFrame frame) {
return Words.toAddress(frame.getStackItem(1));
}

@Override
protected Wei value(final MessageFrame frame) {
return Wei.wrap(frame.getStackItem(2));
}

@Override
protected Wei apparentValue(final MessageFrame frame) {
return value(frame);
}

@Override
protected long inputDataOffset(final MessageFrame frame) {
return clampedToLong(frame.getStackItem(3));
}

@Override
protected long inputDataLength(final MessageFrame frame) {
return clampedToLong(frame.getStackItem(4));
}

@Override
protected long outputDataOffset(final MessageFrame frame) {
return clampedToLong(frame.getStackItem(5));
}

@Override
protected long outputDataLength(final MessageFrame frame) {
return clampedToLong(frame.getStackItem(6));
}

@Override
protected Address address(final MessageFrame frame) {
return to(frame);
}

@Override
protected Address sender(final MessageFrame frame) {
return frame.getAuthorizedBy();
}

@Override
public long gasAvailableForChildCall(final MessageFrame frame) {
return gasCalculator().gasAvailableForChildCall(frame, gas(frame), !value(frame).isZero());
}

@Override
public OperationResult execute(final MessageFrame frame, final EVM evm) {
if (frame.isStatic() && !value(frame).isZero()) {
return new OperationResult(cost(frame, true), ExceptionalHaltReason.ILLEGAL_STATE_CHANGE);
} else if (frame.getAuthorizedBy() != null) {
return super.execute(frame, evm);
} else {
frame.pushStackItem(Bytes32.ZERO);
return new OperationResult(cost(frame, true), null);
}
}
}
Loading

0 comments on commit 1c7fe5a

Please sign in to comment.