Skip to content

Commit

Permalink
Verkle 645 (#7004)
Browse files Browse the repository at this point in the history
* fix codecopy, call operation and code deployment issues
* add push modification
* gas cost modification
* call value transfer cost fix, added non-accumulating method for touchCodeChunks
* consolidate changes into PragueGasCalculator
* add eip4762 definiton and gas calculator, revert prague
* refactor access witness code part

Signed-off-by: Karim Taam <karim.t2am@gmail.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
Co-authored-by: Karim Taam <karim.t2am@gmail.com>
  • Loading branch information
garyschulte and matkt committed Apr 29, 2024
1 parent ecbdd5f commit 5e1f384
Show file tree
Hide file tree
Showing 32 changed files with 824 additions and 463 deletions.
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

0 comments on commit 5e1f384

Please sign in to comment.