Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Cancun evm support web3 #9756

Open
wants to merge 6 commits into
base: main
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
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ dependencies {
api("software.amazon.awssdk:bom:2.29.9")
api("uk.org.webcompere:system-stubs-jupiter:2.1.7")
api("org.web3j:core:4.12.2")
api("tech.pegasys:jc-kzg-4844:0.8.0")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Needed for KZGPointEvalPrecompiledContract.init(); method during evm initialization.

}
}

Expand Down
2 changes: 1 addition & 1 deletion hedera-mirror-web3/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ web3j {
}

val historicalSolidityVersion = "0.8.7"
val latestSolidityVersion = "0.8.24"
val latestSolidityVersion = "0.8.25"

// Define "testHistorical" source set needed for the test historical solidity contracts and web3j
sourceSets {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.hedera.hapi.node.base.SemanticVersion;
import com.hedera.mirror.web3.evm.contracts.execution.MirrorEvmMessageCallProcessor;
import com.hedera.mirror.web3.evm.contracts.execution.MirrorEvmMessageCallProcessorV30;
import com.hedera.mirror.web3.evm.contracts.execution.MirrorEvmMessageCallProcessorV50;
import com.hedera.mirror.web3.evm.contracts.execution.traceability.MirrorOperationTracer;
import com.hedera.mirror.web3.evm.contracts.execution.traceability.OpcodeTracer;
import com.hedera.mirror.web3.evm.contracts.execution.traceability.TracerType;
Expand All @@ -48,6 +49,7 @@
import com.hedera.services.evm.contracts.operations.HederaSelfDestructOperation;
import com.hedera.services.evm.contracts.operations.HederaSelfDestructOperationV038;
import com.hedera.services.evm.contracts.operations.HederaSelfDestructOperationV046;
import com.hedera.services.evm.contracts.operations.HederaSelfDestructOperationV050;
import com.hedera.services.txns.crypto.AbstractAutoCreationLogic;
import com.hedera.services.txns.util.PrngLogic;
import java.util.EnumMap;
Expand All @@ -70,6 +72,7 @@
import org.hyperledger.besu.evm.operation.ExtCodeHashOperation;
import org.hyperledger.besu.evm.operation.OperationRegistry;
import org.hyperledger.besu.evm.operation.SelfDestructOperation;
import org.hyperledger.besu.evm.precompile.KZGPointEvalPrecompiledContract;
import org.hyperledger.besu.evm.precompile.PrecompileContractRegistry;
import org.hyperledger.besu.evm.processor.ContractCreationProcessor;
import org.hyperledger.besu.evm.processor.MessageCallProcessor;
Expand Down Expand Up @@ -115,7 +118,8 @@ public class EvmConfiguration {
public static final SemanticVersion EVM_VERSION_0_34 = new SemanticVersion(0, 34, 0, "", "");
public static final SemanticVersion EVM_VERSION_0_38 = new SemanticVersion(0, 38, 0, "", "");
public static final SemanticVersion EVM_VERSION_0_46 = new SemanticVersion(0, 46, 0, "", "");
public static final SemanticVersion EVM_VERSION = EVM_VERSION_0_46;
public static final SemanticVersion EVM_VERSION_0_50 = new SemanticVersion(0, 50, 0, "", "");
public static final SemanticVersion EVM_VERSION = EVM_VERSION_0_50;
private final CacheProperties cacheProperties;
private final MirrorNodeEvmProperties mirrorNodeEvmProperties;
private final GasCalculatorHederaV22 gasCalculator;
Expand Down Expand Up @@ -243,12 +247,14 @@ Map<SemanticVersion, Provider<ContractCreationProcessor>> contractCreationProces
final ContractCreationProcessor contractCreationProcessor30,
final ContractCreationProcessor contractCreationProcessor34,
final ContractCreationProcessor contractCreationProcessor38,
final ContractCreationProcessor contractCreationProcessor46) {
final ContractCreationProcessor contractCreationProcessor46,
final ContractCreationProcessor contractCreationProcessor50) {
Map<SemanticVersion, Provider<ContractCreationProcessor>> processorsMap = new HashMap<>();
processorsMap.put(EVM_VERSION_0_30, () -> contractCreationProcessor30);
processorsMap.put(EVM_VERSION_0_34, () -> contractCreationProcessor34);
processorsMap.put(EVM_VERSION_0_38, () -> contractCreationProcessor38);
processorsMap.put(EVM_VERSION_0_46, () -> contractCreationProcessor46);
processorsMap.put(EVM_VERSION_0_50, () -> contractCreationProcessor50);
return processorsMap;
}

Expand All @@ -257,13 +263,14 @@ Map<SemanticVersion, Provider<MessageCallProcessor>> messageCallProcessors(
MirrorEvmMessageCallProcessorV30 mirrorEvmMessageCallProcessor30,
MirrorEvmMessageCallProcessor mirrorEvmMessageCallProcessor34,
MirrorEvmMessageCallProcessor mirrorEvmMessageCallProcessor38,
MirrorEvmMessageCallProcessor mirrorEvmMessageCallProcessor46) {
MirrorEvmMessageCallProcessor mirrorEvmMessageCallProcessor46,
MirrorEvmMessageCallProcessorV50 mirrorEvmMessageCallProcessor50) {
Map<SemanticVersion, Provider<MessageCallProcessor>> processorsMap = new HashMap<>();
processorsMap.put(EVM_VERSION_0_30, () -> mirrorEvmMessageCallProcessor30);
processorsMap.put(EVM_VERSION_0_34, () -> mirrorEvmMessageCallProcessor34);
processorsMap.put(EVM_VERSION_0_38, () -> mirrorEvmMessageCallProcessor38);
processorsMap.put(EVM_VERSION_0_46, () -> mirrorEvmMessageCallProcessor46);

processorsMap.put(EVM_VERSION_0_50, () -> mirrorEvmMessageCallProcessor50);
return processorsMap;
}

Expand Down Expand Up @@ -356,6 +363,24 @@ EVM evm046(
MainnetEVMs::registerShanghaiOperations);
}

@Bean
EVM evm050(
final HederaPrngSeedOperation prngSeedOperation,
final HederaSelfDestructOperationV050 hederaSelfDestructOperationV050,
final HederaBalanceOperationV038 hederaBalanceOperationV038) {
KZGPointEvalPrecompiledContract.init();
return evm(
gasCalculator,
mirrorNodeEvmProperties,
prngSeedOperation,
hederaBlockHashOperation,
hederaExtCodeHashOperationV038,
hederaSelfDestructOperationV050,
hederaBalanceOperationV038,
EvmSpecVersion.CANCUN,
MainnetEVMs::registerCancunOperations);
}

@Bean
HederaPrngSeedOperation hederaPrngSeedOperation(final GasCalculator gasCalculator, final PrngLogic prngLogic) {
return new HederaPrngSeedOperation(gasCalculator, prngLogic);
Expand Down Expand Up @@ -384,7 +409,12 @@ HederaBalanceOperationV038 hederaBalanceOperationV038(final GasCalculator gasCal

@Bean
HederaSelfDestructOperationV046 hederaSelfDestructOperationV046(final GasCalculator gasCalculator) {
return new HederaSelfDestructOperationV046(gasCalculator, addressValidator, systemAccountDetector);
return new HederaSelfDestructOperationV046(gasCalculator, addressValidator, systemAccountDetector, false);
}

@Bean
HederaSelfDestructOperationV050 hederaSelfDestructOperationV050(final GasCalculator gasCalculator) {
return new HederaSelfDestructOperationV050(gasCalculator, addressValidator, systemAccountDetector);
}

@Bean
Expand Down Expand Up @@ -412,6 +442,11 @@ public ContractCreationProcessor contractCreationProcessor46(@Qualifier("evm046"
return contractCreationProcessor(evm);
}

@Bean
public ContractCreationProcessor contractCreationProcessor50(@Qualifier("evm050") EVM evm) {
return contractCreationProcessor(evm);
}

@Bean
public MirrorEvmMessageCallProcessor mirrorEvmMessageCallProcessor34(@Qualifier("evm034") EVM evm) {
return mirrorEvmMessageCallProcessor(evm);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import static com.hedera.services.store.contracts.precompile.PrngSystemPrecompiledContract.PRNG_PRECOMPILE_ADDRESS;

import com.hedera.mirror.web3.evm.properties.MirrorNodeEvmProperties;
import com.hedera.services.contracts.gascalculator.GasCalculatorHederaV22;
import com.hedera.services.fees.BasicHbarCentExchange;
import com.hedera.services.store.contracts.precompile.ExchangeRatePrecompiledContract;
import com.hedera.services.store.contracts.precompile.HTSPrecompiledContract;
Expand All @@ -31,6 +30,7 @@
import java.util.HashMap;
import java.util.Map;
import lombok.Getter;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.evm.precompile.PrecompiledContract;

@Named
Expand All @@ -42,7 +42,7 @@ public class PrecompilesHolder implements PrecompiledContractProvider {
PrecompilesHolder(
final MirrorNodeEvmProperties mirrorNodeEvmProperties,
final PrngSystemPrecompiledContract prngSystemPrecompiledContract,
final GasCalculatorHederaV22 gasCalculator,
final GasCalculator gasCalculator,
final BasicHbarCentExchange basicHbarCentExchange,
final HTSPrecompiledContract htsPrecompiledContract) {
hederaPrecompiles = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,22 @@ public class ServicesConfiguration {
private static final int SYSTEM_ACCOUNT_BOUNDARY = 750;
private static final int STRICT_SYSTEM_ACCOUNT_BOUNDARY = 999;

@Bean
static Predicate<Address> systemAccountDetector() {
// all addresses between 0-750 (inclusive) are treated as system accounts
// from the perspective of the EVM when executing Call, Balance, and SelfDestruct operations
return address -> address.numberOfLeadingZeroBytes() >= 18
&& Integer.compareUnsigned(address.getInt(16), SYSTEM_ACCOUNT_BOUNDARY) <= 0;
}

@Bean
static Predicate<Address> strictSystemAccountDetector() {
// all addresses between 0-999 (inclusive) are treated as system accounts
// from the perspective of the EVM when executing ExtCode operations
return address -> address.numberOfLeadingZeroBytes() >= 18
&& Integer.compareUnsigned(address.getInt(16), STRICT_SYSTEM_ACCOUNT_BOUNDARY) <= 0;
}

@Bean
GasCalculatorHederaV22 gasCalculatorHederaV22(
final BasicFcfsUsagePrices usagePricesProvider, final BasicHbarCentExchange hbarCentExchange) {
Expand Down Expand Up @@ -686,12 +702,11 @@ PrngLogic prngLogic(final RecordFileRepository recordFileRepository) {

@Bean
PrngSystemPrecompiledContract prngSystemPrecompiledContract(
final GasCalculatorHederaV22 gasCalculatorHederaV22,
final GasCalculator gasCalculator,
final PrngLogic prngLogic,
final LivePricesSource livePricesSource,
final PrecompilePricingUtils precompilePricingUtils) {
return new PrngSystemPrecompiledContract(
gasCalculatorHederaV22, prngLogic, livePricesSource, precompilePricingUtils);
return new PrngSystemPrecompiledContract(gasCalculator, prngLogic, livePricesSource, precompilePricingUtils);
}

@Bean
Expand Down Expand Up @@ -781,22 +796,6 @@ BiPredicate<Address, MessageFrame> preV38AddressValidator() {
return (address, frame) -> frame.getWorldUpdater().get(address) != null;
}

@Bean
static Predicate<Address> systemAccountDetector() {
// all addresses between 0-750 (inclusive) are treated as system accounts
// from the perspective of the EVM when executing Call, Balance, and SelfDestruct operations
return address -> address.numberOfLeadingZeroBytes() >= 18
&& Integer.compareUnsigned(address.getInt(16), SYSTEM_ACCOUNT_BOUNDARY) <= 0;
}

@Bean
static Predicate<Address> strictSystemAccountDetector() {
// all addresses between 0-999 (inclusive) are treated as system accounts
// from the perspective of the EVM when executing ExtCode operations
return address -> address.numberOfLeadingZeroBytes() >= 18
&& Integer.compareUnsigned(address.getInt(16), STRICT_SYSTEM_ACCOUNT_BOUNDARY) <= 0;
}

@Bean
CreateChecks createChecks(final OptionValidator optionValidator) {
return new CreateChecks(optionValidator);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import com.hedera.mirror.web3.evm.config.PrecompiledContractProvider;
import com.hedera.mirror.web3.evm.store.contract.EntityAddressSequencer;
import com.hedera.mirror.web3.evm.store.contract.HederaEvmStackedWorldStateUpdater;
import com.hedera.services.contracts.gascalculator.GasCalculatorHederaV22;
import com.hedera.services.ledger.BalanceChange;
import com.hedera.services.txns.crypto.AbstractAutoCreationLogic;
import com.hedera.services.utils.EntityIdUtils;
Expand All @@ -40,6 +39,7 @@
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.precompile.MainnetPrecompiledContracts;
import org.hyperledger.besu.evm.precompile.PrecompileContractRegistry;
import org.hyperledger.besu.evm.tracing.OperationTracer;
Expand All @@ -54,7 +54,7 @@ public MirrorEvmMessageCallProcessor(
final EVM evm,
final PrecompileContractRegistry precompiles,
final PrecompiledContractProvider precompilesHolder,
final GasCalculatorHederaV22 gasCalculator,
final GasCalculator gasCalculator,
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't we use our own GasCalculator, instead of built-in from besu?

Copy link
Contributor Author

@kselveliev kselveliev Nov 14, 2024

Choose a reason for hiding this comment

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

Under the hood it will pick our GasCalculatorHederaV22 bean since it's our only bean implementing the GasCalculator interface. Just checked it locally with instance off and it picks GasCalculatorHederaV22 under the hood.

final Predicate<Address> systemAccountDetector) {
super(evm, precompiles, precompilesHolder.getHederaPrecompiles(), systemAccountDetector);
this.autoCreationLogic = autoCreationLogic;
Expand All @@ -65,6 +65,7 @@ public MirrorEvmMessageCallProcessor(

/**
* This logic is copied from hedera-services HederaMessageCallProcessor.
*
* @param frame
* @param operationTracer
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
package com.hedera.mirror.web3.evm.contracts.execution;

import com.hedera.mirror.web3.evm.config.PrecompiledContractProvider;
import com.hedera.services.contracts.gascalculator.GasCalculatorHederaV22;
import jakarta.inject.Named;
import java.util.function.Predicate;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.evm.EVM;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.evm.precompile.MainnetPrecompiledContracts;
import org.hyperledger.besu.evm.precompile.PrecompileContractRegistry;

Expand All @@ -32,7 +32,7 @@ public MirrorEvmMessageCallProcessorV30(
@Named("evm030") EVM v30,
PrecompileContractRegistry precompiles,
final PrecompiledContractProvider precompilesHolder,
final GasCalculatorHederaV22 gasCalculator,
final GasCalculator gasCalculator,
final Predicate<Address> systemAccountDetector) {
super(v30, precompiles, precompilesHolder.getHederaPrecompiles(), systemAccountDetector);
MainnetPrecompiledContracts.populateForIstanbul(precompiles, gasCalculator);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (C) 2024 Hedera Hashgraph, LLC
*
* 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 com.hedera.mirror.web3.evm.contracts.execution;

import com.hedera.mirror.web3.evm.config.PrecompiledContractProvider;
import com.hedera.mirror.web3.evm.store.contract.EntityAddressSequencer;
import com.hedera.services.txns.crypto.AbstractAutoCreationLogic;
import jakarta.inject.Named;
import java.util.function.Predicate;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.evm.EVM;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.evm.precompile.MainnetPrecompiledContracts;
import org.hyperledger.besu.evm.precompile.PrecompileContractRegistry;

@Named
@SuppressWarnings("java:S110")
public class MirrorEvmMessageCallProcessorV50 extends MirrorEvmMessageCallProcessor {
public MirrorEvmMessageCallProcessorV50(
final AbstractAutoCreationLogic autoCreationLogic,
final EntityAddressSequencer entityAddressSequencer,
@Named("evm050") EVM v50,
final PrecompileContractRegistry precompiles,
final PrecompiledContractProvider precompilesHolder,
final GasCalculator gasCalculator,
final Predicate<Address> systemAccountDetector) {
super(
autoCreationLogic,
entityAddressSequencer,
v50,
precompiles,
precompilesHolder,
gasCalculator,
systemAccountDetector);

MainnetPrecompiledContracts.populateForCancun(precompiles, gasCalculator);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import static com.hedera.mirror.web3.evm.config.EvmConfiguration.EVM_VERSION_0_34;
import static com.hedera.mirror.web3.evm.config.EvmConfiguration.EVM_VERSION_0_38;
import static com.hedera.mirror.web3.evm.config.EvmConfiguration.EVM_VERSION_0_46;
import static com.hedera.mirror.web3.evm.config.EvmConfiguration.EVM_VERSION_0_50;
import static com.swirlds.common.utility.CommonUtils.unhex;
import static com.swirlds.state.spi.HapiUtils.SEMANTIC_VERSION_COMPARATOR;

Expand Down Expand Up @@ -84,7 +85,7 @@ public class MirrorNodeEvmProperties implements EvmProperties {

@Getter
@NotNull
private EvmSpecVersion evmSpecVersion = EvmSpecVersion.SHANGHAI;
private EvmSpecVersion evmSpecVersion = EvmSpecVersion.CANCUN;

@Getter
@NotNull
Expand Down Expand Up @@ -331,6 +332,8 @@ private static NavigableMap<Long, SemanticVersion> mainnetEvmVersionsMap() {
evmVersionsMap.put(44029066L, EVM_VERSION_0_34);
evmVersionsMap.put(49117794L, EVM_VERSION_0_38);
evmVersionsMap.put(60258042L, EVM_VERSION_0_46);
evmVersionsMap.put(65435845L, EVM_VERSION_0_50);

return Collections.unmodifiableNavigableMap(evmVersionsMap);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,11 @@
import org.hyperledger.besu.evm.tracing.OperationTracer;

/**
* Stateless invariant copy of its hedera-services counterpart. It is used to process EVM transactions in
* an asynchronous manner.
*
* Stateless invariant copy of its hedera-services counterpart. It is used to process EVM transactions in an
* asynchronous manner.
* <p>
* All class fields are final and immutable and some of them moved in the execute method.
*
* */
*/
public class HederaEvmTxProcessor {
private static final int MAX_STACK_SIZE = 1024;

Expand Down Expand Up @@ -85,17 +84,15 @@ protected HederaEvmTxProcessor(
/**
* Executes the {@link MessageFrame} of the EVM transaction and fills execution results into a field.
*
* @param sender The origin {@link MutableAccount} that initiates the transaction
* @param receiver the priority form of the receiving {@link Address} (i.e., EIP-1014 if
* present); or the newly created address
* @param gasPrice GasPrice to use for gas calculations
* @param gasLimit Externally provided gas limit
* @param value transaction value
* @param payload transaction payload. For Create transactions, the bytecode + constructor
* arguments
* @param isStatic Whether the execution is static
* @param mirrorReceiver the mirror form of the receiving {@link Address}; or the newly created
* address
* @param sender The origin {@link MutableAccount} that initiates the transaction
* @param receiver the priority form of the receiving {@link Address} (i.e., EIP-1014 if present); or the
* newly created address
* @param gasPrice GasPrice to use for gas calculations
* @param gasLimit Externally provided gas limit
* @param value transaction value
* @param payload transaction payload. For Create transactions, the bytecode + constructor arguments
* @param isStatic Whether the execution is static
* @param mirrorReceiver the mirror form of the receiving {@link Address}; or the newly created address
*/
@SuppressWarnings("java:S107")
public HederaEvmTransactionProcessingResult execute(
Expand Down
Loading
Loading