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

Verkle 645 #7004

Merged
merged 13 commits into from Apr 29, 2024
Expand Up @@ -637,7 +637,7 @@ && isDescendantOf(newHead, blockchain.getChainHeadHeader())) {
return ForkchoiceResult.withResult(newFinalized, Optional.of(newHead));
}

private boolean setNewHead(final MutableBlockchain blockchain, final BlockHeader newHead) {
public boolean setNewHead(final MutableBlockchain blockchain, final BlockHeader newHead) {

if (newHead.getHash().equals(blockchain.getChainHeadHash())) {
LOG.atDebug()
Expand Down
Expand Up @@ -6,12 +6,8 @@

public interface AccessWitness {

void merge(AccessWitness other);

List<Address> keys();

AccessWitness copy();

long touchAndChargeProofOfAbsence(Address address);

long touchAndChargeValueTransfer(Address caller, Address target);
Expand All @@ -33,4 +29,11 @@ public interface AccessWitness {
List<UInt256> getStorageSlotTreeIndexes(UInt256 storageKey);

long touchCodeChunksUponContractCreation(Address address, long codeLength);

long touchCodeChunks(Address address, long offset, long readSize, long codeLength);

default long touchCodeChunksWithoutAccessCost(
final Address address, final long offset, final long readSize, final long codeLength) {
return touchCodeChunks(address, offset, readSize, codeLength);
}
}
Expand Up @@ -179,7 +179,9 @@ public ProtocolSpecBuilder cancunDefinition(final GenesisConfigOptions genesisCo
}

public ProtocolSpecBuilder pragueDefinition(final GenesisConfigOptions genesisConfigOptions) {
return MainnetProtocolSpecs.pragueDefinition(
// TODO: this is for VERKLE devnet
// return MainnetProtocolSpecs.pragueDefinition(
return MainnetProtocolSpecs.eip4762Definition(
chainId,
contractSizeLimit,
evmStackSize,
Expand Down
Expand Up @@ -31,7 +31,6 @@
import org.hyperledger.besu.ethereum.core.Withdrawal;
import org.hyperledger.besu.ethereum.core.feemarket.CoinbaseFeePriceCalculator;
import org.hyperledger.besu.ethereum.mainnet.ClearEmptyAccountStrategy.ClearEmptyAccount;
import org.hyperledger.besu.ethereum.mainnet.ClearEmptyAccountStrategy.ClearEmptyAccountWithException;
import org.hyperledger.besu.ethereum.mainnet.ClearEmptyAccountStrategy.NotClearEmptyAccount;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecBuilder.BlockValidatorBuilder;
import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket;
Expand All @@ -50,6 +49,7 @@
import org.hyperledger.besu.evm.gascalculator.ByzantiumGasCalculator;
import org.hyperledger.besu.evm.gascalculator.CancunGasCalculator;
import org.hyperledger.besu.evm.gascalculator.ConstantinopleGasCalculator;
import org.hyperledger.besu.evm.gascalculator.Eip4762GasCalculator;
import org.hyperledger.besu.evm.gascalculator.FrontierGasCalculator;
import org.hyperledger.besu.evm.gascalculator.HomesteadGasCalculator;
import org.hyperledger.besu.evm.gascalculator.IstanbulGasCalculator;
Expand Down Expand Up @@ -728,52 +728,6 @@ static ProtocolSpecBuilder cancunDefinition(
.name("Cancun");
}

// TODO FIX THAT TO HAVE CORRECT CONFIGURATION
static ProtocolSpecBuilder pragueDefinition(
final Optional<BigInteger> chainId,
final OptionalInt configContractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) {
final int stackSizeLimit = configStackSizeLimit.orElse(MessageFrame.DEFAULT_MAX_STACK_SIZE);

final ClearEmptyAccountStrategy clearEmptyAccountStrategy =
new ClearEmptyAccountWithException(
List.of(HistoricalBlockHashProcessor.HISTORICAL_BLOCKHASH_ADDRESS));
return shanghaiDefinition(
chainId,
configContractSizeLimit,
configStackSizeLimit,
enableRevertReason,
genesisConfigOptions,
evmConfiguration,
miningParameters)
.gasCalculator(PragueGasCalculator::new)
.transactionProcessorBuilder(
(gasCalculator,
feeMarket,
transactionValidator,
contractCreationProcessor,
messageCallProcessor) ->
new MainnetTransactionProcessor(
gasCalculator,
transactionValidator,
contractCreationProcessor,
messageCallProcessor,
clearEmptyAccountStrategy,
true,
stackSizeLimit,
feeMarket,
CoinbaseFeePriceCalculator.eip1559()))
.withdrawalsProcessor(new WithdrawalsProcessor(clearEmptyAccountStrategy))
.historicalBlockHashProcessor(
new HistoricalBlockHashProcessor(genesisConfigOptions.getPragueTime().orElse(0)))
.name("Prague");
}

/* //TODO REACTIVATE
static ProtocolSpecBuilder pragueDefinition(
final Optional<BigInteger> chainId,
final OptionalInt configContractSizeLimit,
Expand Down Expand Up @@ -819,7 +773,55 @@ static ProtocolSpecBuilder pragueDefinition(
.exitsValidator(new ValidatorExitsValidator.AllowedExits())
.name("Prague");
}
*/

static ProtocolSpecBuilder eip4762Definition(
final Optional<BigInteger> chainId,
final OptionalInt configContractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) {

// extra variables need to support flipping the warm coinbase flag.
final int stackSizeLimit = configStackSizeLimit.orElse(MessageFrame.DEFAULT_MAX_STACK_SIZE);
final ClearEmptyAccountStrategy clearEmptyAccountStrategy =
new ClearEmptyAccountStrategy.ClearEmptyAccountWithException(
List.of(HistoricalBlockHashProcessor.HISTORICAL_BLOCKHASH_ADDRESS));
return shanghaiDefinition(
chainId,
configContractSizeLimit,
configStackSizeLimit,
enableRevertReason,
genesisConfigOptions,
evmConfiguration,
miningParameters)
.gasCalculator(Eip4762GasCalculator::new)
.evmBuilder(
(gasCalculator, jdCacheConfig) ->
MainnetEVMs.eip4762(
gasCalculator, chainId.orElse(BigInteger.ZERO), evmConfiguration))
.transactionProcessorBuilder(
(gasCalculator,
feeMarket,
transactionValidatorFactory,
contractCreationProcessor,
messageCallProcessor) ->
new MainnetTransactionProcessor(
gasCalculator,
transactionValidatorFactory,
contractCreationProcessor,
messageCallProcessor,
clearEmptyAccountStrategy,
true,
stackSizeLimit,
feeMarket,
CoinbaseFeePriceCalculator.eip1559()))
.withdrawalsProcessor(new WithdrawalsProcessor(clearEmptyAccountStrategy))
.historicalBlockHashProcessor(
new HistoricalBlockHashProcessor(genesisConfigOptions.getPragueTime().orElse(0)))
.name("eip4762");
}

static ProtocolSpecBuilder futureEipsDefinition(
final Optional<BigInteger> chainId,
Expand Down
Expand Up @@ -21,10 +21,10 @@

import org.hyperledger.besu.collections.trie.BytesTrieSet;
import org.hyperledger.besu.datatypes.AccessListEntry;
import org.hyperledger.besu.datatypes.AccessWitness;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.AccessWitness;
import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.feemarket.CoinbaseFeePriceCalculator;
Expand Down Expand Up @@ -337,7 +337,7 @@ public TransactionProcessingResult processTransaction(
if (warmCoinbase) {
addressList.add(miningBeneficiary);
}
final AccessWitness accessWitness = new AccessWitness();
final AccessWitness accessWitness = gasCalculator.newAccessWitness();
final long intrinsicGas =
gasCalculator.transactionIntrinsicGasCost(
transaction.getPayload(), transaction.isContractCreation());
Expand Down Expand Up @@ -462,11 +462,11 @@ public TransactionProcessingResult processTransaction(
final Wei balancePriorToRefund = sender.getBalance();
sender.incrementBalance(refundedWei);
LOG.atTrace()
.setMessage("refunded sender {} {} wei ({} -> {})")
.setMessage("refunded sender {} {} wei (balance before:{} -> after:{})")
.addArgument(senderAddress)
.addArgument(refundedWei)
.addArgument(balancePriorToRefund)
.addArgument(sender.getBalance())
.addArgument(refundedWei.toShortHexString())
.addArgument(balancePriorToRefund.toShortHexString())
.addArgument(sender.getBalance().toShortHexString())
.log();
final long gasUsedByTransaction = transaction.getGasLimit() - initialFrame.getRemainingGas();
LOG.info(
Expand Down
Expand Up @@ -171,7 +171,7 @@ public static GetBlockHeadersData create(

public static GetBlockHeadersData create(
final Hash hash, final int maxHeaders, final int skip, final boolean reverse) {
//System.out.println("create " + hash + " " + maxHeaders);
// System.out.println("create " + hash + " " + maxHeaders);
return new GetBlockHeadersData(
Optional.of(hash), OptionalLong.empty(), maxHeaders, skip, reverse);
}
Expand Down
48 changes: 13 additions & 35 deletions evm/src/main/java/org/hyperledger/besu/evm/EVM.java
Expand Up @@ -15,7 +15,6 @@
package org.hyperledger.besu.evm;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.hyperledger.besu.evm.operation.PushOperation.PUSH_BASE;
import static org.hyperledger.besu.evm.operation.SwapOperation.SWAP_BASE;

import org.hyperledger.besu.datatypes.Hash;
Expand Down Expand Up @@ -53,7 +52,6 @@
import org.hyperledger.besu.evm.operation.OrOperation;
import org.hyperledger.besu.evm.operation.PopOperation;
import org.hyperledger.besu.evm.operation.Push0Operation;
import org.hyperledger.besu.evm.operation.PushOperation;
import org.hyperledger.besu.evm.operation.SDivOperation;
import org.hyperledger.besu.evm.operation.SGtOperation;
import org.hyperledger.besu.evm.operation.SLtOperation;
Expand Down Expand Up @@ -183,14 +181,26 @@ public void runToHalt(final MessageFrame frame, final OperationTracer tracing) {

var operationTracer = tracing == OperationTracer.NO_TRACING ? null : tracing;
byte[] code = frame.getCode().getBytes().toArrayUnsafe();

Operation[] operationArray = operations.getOperations();
while (frame.getState() == MessageFrame.State.CODE_EXECUTING) {
Operation currentOperation;
int opcode;
int pc = frame.getPC();

long statelessGas = 0;
try {
opcode = code[pc] & 0xff;
currentOperation = operationArray[opcode];

if (!frame.wasCreatedInTransaction(frame.getContractAddress())) {
statelessGas =
frame
.getAccessWitness()
.touchCodeChunks(frame.getContractAddress(), pc, 1, code.length);
frame.decrementRemainingGas(statelessGas);
}

} catch (ArrayIndexOutOfBoundsException aiiobe) {
opcode = 0;
currentOperation = endOfScriptStop;
Expand Down Expand Up @@ -235,39 +245,6 @@ public void runToHalt(final MessageFrame frame, final OperationTracer tracing) {
enableShanghai
? Push0Operation.staticOperation(frame)
: InvalidOperation.INVALID_RESULT;
case 0x60, // PUSH1-32
0x61,
0x62,
0x63,
0x64,
0x65,
0x66,
0x67,
0x68,
0x69,
0x6a,
0x6b,
0x6c,
0x6d,
0x6e,
0x6f,
0x70,
0x71,
0x72,
0x73,
0x74,
0x75,
0x76,
0x77,
0x78,
0x79,
0x7a,
0x7b,
0x7c,
0x7d,
0x7e,
0x7f ->
PushOperation.staticOperation(frame, code, pc, opcode - PUSH_BASE);
case 0x80, // DUP1-16
0x81,
0x82,
Expand Down Expand Up @@ -312,6 +289,7 @@ public void runToHalt(final MessageFrame frame, final OperationTracer tracing) {
} catch (final UnderflowException ue) {
result = UNDERFLOW_RESPONSE;
}

final ExceptionalHaltReason haltReason = result.getHaltReason();
if (haltReason != null) {
LOG.trace("MessageFrame evaluation halted because of {}", haltReason);
Expand Down
51 changes: 51 additions & 0 deletions evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java
Expand Up @@ -1087,6 +1087,57 @@ public static void registerBogotaOperations(
registerOsakaOperations(registry, gasCalculator, chainID);
}

/**
* eip4762 evm.
*
* @param gasCalculator the gas calculator
* @param chainId the chain id
* @param evmConfiguration the evm configuration
* @return the evm
*/
public static EVM eip4762(
final GasCalculator gasCalculator,
final BigInteger chainId,
final EvmConfiguration evmConfiguration) {
return new EVM(
eip4762Operations(gasCalculator, chainId),
gasCalculator,
evmConfiguration,
EvmSpecVersion.FUTURE_EIPS);
}

/**
* Operation registry for eip472's operations.
*
* @param gasCalculator the gas calculator
* @param chainId the chain id
* @return the operation registry
*/
public static OperationRegistry eip4762Operations(
final GasCalculator gasCalculator, final BigInteger chainId) {
OperationRegistry operationRegistry = new OperationRegistry();
registerEip4762Operations(operationRegistry, gasCalculator, chainId);
return operationRegistry;
}

/**
* Register eip4762 operations.
*
* @param registry the registry
* @param gasCalculator the gas calculator
* @param chainID the chain id
*/
public static void registerEip4762Operations(
final OperationRegistry registry,
final GasCalculator gasCalculator,
final BigInteger chainID) {
// basing off of shanghai for devnet-6
registerShanghaiOperations(registry, gasCalculator, chainID);
registry.put(new BlockHashOperation(gasCalculator, true));
// mimic a weird behavior by geth that ignores eip-1706
registry.put(new SStoreOperation(gasCalculator, 272L));
}

/**
* Future eips evm.
*
Expand Down