diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java index 7d235fb3a39..927e4cd8a29 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java @@ -363,6 +363,7 @@ public TransactionProcessingResult processTransaction( .initialGas(gasAvailable) .originator(senderAddress) .gasPrice(transactionGasPrice) + .blobGasPrice(blobGasPrice) .sender(senderAddress) .value(transaction.getValue()) .apparentValue(transaction.getValue()) diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/MessageFrameTestFixture.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/MessageFrameTestFixture.java index bfd56cbaa5d..262657872f5 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/MessageFrameTestFixture.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/MessageFrameTestFixture.java @@ -48,6 +48,7 @@ public class MessageFrameTestFixture { private Address originator = DEFAUT_ADDRESS; private Address contract = DEFAUT_ADDRESS; private Wei gasPrice = Wei.ZERO; + private Wei blobGasPrice = Wei.ZERO; private Wei value = Wei.ZERO; private Bytes inputData = Bytes.EMPTY; private Code code = CodeV0.EMPTY_CODE; @@ -117,6 +118,11 @@ public MessageFrameTestFixture gasPrice(final Wei gasPrice) { return this; } + public MessageFrameTestFixture blobGasPrice(final Wei blobGasPrice) { + this.blobGasPrice = blobGasPrice; + return this; + } + public MessageFrameTestFixture value(final Wei value) { this.value = value; return this; @@ -160,6 +166,7 @@ public MessageFrame build() { .address(address) .originator(originator) .gasPrice(gasPrice) + .blobGasPrice(blobGasPrice) .inputData(inputData) .sender(sender) .value(value) diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java index 4c51fc55998..d41dd56093b 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java @@ -116,6 +116,12 @@ void setBytes(final String optionValue) { paramLabel = "") private final Wei gasPriceGWei = Wei.ZERO; + @Option( + names = {"--blob-price"}, + description = "Price of blob gas for this invocation", + paramLabel = "") + private final Wei blobGasPrice = Wei.ZERO; + @Option( names = {"--sender"}, paramLabel = "
", @@ -376,6 +382,7 @@ public void run() { .originator(sender) .sender(sender) .gasPrice(gasPriceGWei) + .blobGasPrice(blobGasPrice) .inputData(callData) .value(ethValue) .apparentValue(ethValue) diff --git a/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java b/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java index 3aad40735d8..7884816ecf0 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java @@ -33,6 +33,7 @@ import org.hyperledger.besu.evm.operation.AndOperation; import org.hyperledger.besu.evm.operation.BalanceOperation; import org.hyperledger.besu.evm.operation.BaseFeeOperation; +import org.hyperledger.besu.evm.operation.BlobBaseFeeOperation; import org.hyperledger.besu.evm.operation.BlobHashOperation; import org.hyperledger.besu.evm.operation.BlockHashOperation; import org.hyperledger.besu.evm.operation.ByteOperation; @@ -856,6 +857,9 @@ public static void registerCancunOperations( // EIP-6780 nerf self destruct registry.put(new SelfDestructOperation(gasCalculator, true)); + + // EIP-7516 BLOBBASEFEE + registry.put(new BlobBaseFeeOperation(gasCalculator)); } /** diff --git a/evm/src/main/java/org/hyperledger/besu/evm/fluent/EVMExecutor.java b/evm/src/main/java/org/hyperledger/besu/evm/fluent/EVMExecutor.java index f25d5259b96..9921f56e64b 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/fluent/EVMExecutor.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/fluent/EVMExecutor.java @@ -58,6 +58,7 @@ public class EVMExecutor { private Address receiver = Address.ZERO; private Address sender = Address.ZERO; private Wei gasPriceGWei = Wei.ZERO; + private Wei blobGasPrice = Wei.ZERO; private Bytes callData = Bytes.EMPTY; private Wei ethValue = Wei.ZERO; private Code code = CodeV0.EMPTY_CODE; @@ -354,6 +355,7 @@ public Bytes execute() { .originator(sender) .sender(sender) .gasPrice(gasPriceGWei) + .blobGasPrice(blobGasPrice) .inputData(callData) .value(ethValue) .apparentValue(ethValue) @@ -457,6 +459,17 @@ public EVMExecutor gasPriceGWei(final Wei gasPriceGWei) { return this; } + /** + * Sets Blob Gas price. + * + * @param blobGasPrice the blob gas price g wei + * @return the evm executor + */ + public EVMExecutor blobGasPrice(final Wei blobGasPrice) { + this.blobGasPrice = blobGasPrice; + return this; + } + /** * Sets Call data. * diff --git a/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java b/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java index a315e899b7a..ed711e3f181 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java @@ -1134,6 +1134,15 @@ public Wei getGasPrice() { return txValues.gasPrice(); } + /** + * Returns the current blob gas price. + * + * @return the current blob gas price + */ + public Wei getBlobGasPrice() { + return txValues.blobGasPrice(); + } + /** * Returns the recipient of the sender. * @@ -1365,6 +1374,7 @@ public static class Builder { private Address originator; private Address contract; private Wei gasPrice; + private Wei blobGasPrice = Wei.ZERO; private Bytes inputData; private Address sender; private Wei value; @@ -1472,6 +1482,17 @@ public Builder gasPrice(final Wei gasPrice) { return this; } + /** + * Sets Blob Gas price. + * + * @param blobGasPrice the blob gas price + * @return the builder + */ + public Builder blobGasPrice(final Wei blobGasPrice) { + this.blobGasPrice = blobGasPrice; + return this; + } + /** * Sets Input data. * @@ -1653,6 +1674,7 @@ private void validate() { checkState(worldUpdater != null, "Missing message frame world updater"); checkState(originator != null, "Missing message frame originator"); checkState(gasPrice != null, "Missing message frame getGasRemaining price"); + checkState(blobGasPrice != null, "Missing message frame blob gas price"); checkState(blockValues != null, "Missing message frame block header"); checkState(miningBeneficiary != null, "Missing mining beneficiary"); checkState(blockHashLookup != null, "Missing block hash lookup"); @@ -1689,6 +1711,7 @@ public MessageFrame build() { UndoTable.of(HashBasedTable.create()), originator, gasPrice, + blobGasPrice, blockValues, new ArrayDeque<>(), miningBeneficiary, diff --git a/evm/src/main/java/org/hyperledger/besu/evm/frame/TxValues.java b/evm/src/main/java/org/hyperledger/besu/evm/frame/TxValues.java index 65f7f47b569..6ef1143530f 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/frame/TxValues.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/frame/TxValues.java @@ -40,6 +40,7 @@ public record TxValues( UndoTable warmedUpStorage, Address originator, Wei gasPrice, + Wei blobGasPrice, BlockValues blockValues, Deque messageFrameStack, Address miningBeneficiary, diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/BlobBaseFeeOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/BlobBaseFeeOperation.java new file mode 100644 index 00000000000..a7168473882 --- /dev/null +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/BlobBaseFeeOperation.java @@ -0,0 +1,41 @@ +/* + * 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 org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.evm.EVM; +import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.evm.gascalculator.GasCalculator; + +/** The Blob Base fee operation. */ +public class BlobBaseFeeOperation extends AbstractFixedCostOperation { + + /** + * Instantiates a new Blob Base fee operation. + * + * @param gasCalculator the gas calculator + */ + public BlobBaseFeeOperation(final GasCalculator gasCalculator) { + super(0x4a, "BLOBBASEFEE", 0, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); + } + + @Override + public OperationResult executeFixedCostOperation(final MessageFrame frame, final EVM evm) { + + final Wei blobGasPrice = frame.getBlobGasPrice(); + frame.pushStackItem(blobGasPrice.toBytes()); + return successResponse; + } +} diff --git a/evm/src/test/java/org/hyperledger/besu/evm/testutils/TestMessageFrameBuilder.java b/evm/src/test/java/org/hyperledger/besu/evm/testutils/TestMessageFrameBuilder.java index 0e7fdb50418..f6b2abd69d9 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/testutils/TestMessageFrameBuilder.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/testutils/TestMessageFrameBuilder.java @@ -47,6 +47,7 @@ public class TestMessageFrameBuilder { private Address originator = DEFAUT_ADDRESS; private Address contract = DEFAUT_ADDRESS; private Wei gasPrice = Wei.ZERO; + private Wei blobGasPrice = Wei.ZERO; private Wei value = Wei.ZERO; private Bytes inputData = Bytes.EMPTY; private Code code = CodeV0.EMPTY_CODE; @@ -91,6 +92,11 @@ public TestMessageFrameBuilder gasPrice(final Wei gasPrice) { return this; } + public TestMessageFrameBuilder blobGasPrice(final Wei blobGasPrice) { + this.blobGasPrice = blobGasPrice; + return this; + } + public TestMessageFrameBuilder value(final Wei value) { this.value = value; return this; @@ -145,6 +151,7 @@ public MessageFrame build() { .address(address) .originator(originator) .gasPrice(gasPrice) + .blobGasPrice(blobGasPrice) .inputData(inputData) .sender(sender) .value(value)