Skip to content

Commit

Permalink
feat: add eth_blobBaseFee (hyperledger#6581)
Browse files Browse the repository at this point in the history
Signed-off-by: Gabriel-Trintinalia <[email protected]>
  • Loading branch information
Gabriel-Trintinalia authored Feb 16, 2024
1 parent 5bf959a commit bc2eed1
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
- Experimental feature `--Xbonsai-code-using-code-hash-enabled` for storing Bonsai code storage by code hash [#6505](https://github.com/hyperledger/besu/pull/6505)
- More accurate column size `storage rocksdb usage` subcommand [#6540](https://github.com/hyperledger/besu/pull/6540)
- Adds `storage rocksdb x-stats` subcommand [#6540](https://github.com/hyperledger/besu/pull/6540)
- New `eth_blobBaseFee`JSON-RPC method [#6581](https://github.com/hyperledger/besu/pull/6581)

### Bug fixes
- Fix the way an advertised host configured with `--p2p-host` is treated when communicating with the originator of a PING packet [#6225](https://github.com/hyperledger/besu/pull/6225)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ public enum RpcMethod {
ETH_CREATE_ACCESS_LIST("eth_createAccessList"),
ETH_FEE_HISTORY("eth_feeHistory"),
ETH_GAS_PRICE("eth_gasPrice"),
ETH_BLOB_BASE_FEE("eth_blobBaseFee"),
ETH_GET_BALANCE("eth_getBalance"),
ETH_GET_BLOCK_BY_HASH("eth_getBlockByHash"),
ETH_GET_BLOCK_BY_NUMBER("eth_getBlockByNumber"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* 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.ethereum.api.jsonrpc.internal.methods;

import static org.hyperledger.besu.ethereum.mainnet.feemarket.ExcessBlobGasCalculator.calculateExcessBlobGasForParent;

import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;

public class EthBlobBaseFee implements JsonRpcMethod {

final Blockchain blockchain;

private final ProtocolSchedule protocolSchedule;

public EthBlobBaseFee(final Blockchain blockchain, final ProtocolSchedule protocolSchedule) {
this.blockchain = blockchain;
this.protocolSchedule = protocolSchedule;
}

@Override
public String getName() {
return RpcMethod.ETH_BLOB_BASE_FEE.getMethodName();
}

@Override
public JsonRpcResponse response(final JsonRpcRequestContext requestContext) {
return new JsonRpcSuccessResponse(
requestContext.getRequest().getId(), Quantity.create(computeNextBlobBaseFee()));
}

private Wei computeNextBlobBaseFee() {
final BlockHeader header = blockchain.getChainHeadHeader();
ProtocolSpec spec = protocolSchedule.getForNextBlockHeader(header, header.getTimestamp());
return spec.getFeeMarket().blobGasPricePerGas(calculateExcessBlobGasForParent(spec, header));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthAccounts;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthBlobBaseFee;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthBlockNumber;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthCall;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthChainId;
Expand Down Expand Up @@ -181,6 +182,7 @@ protected Map<String, JsonRpcMethod> create() {
new EthSubmitHashRate(miningCoordinator),
new EthChainId(protocolSchedule.getChainId()),
new EthGetMinerDataByBlockHash(blockchainQueries, protocolSchedule),
new EthGetMinerDataByBlockNumber(blockchainQueries, protocolSchedule));
new EthGetMinerDataByBlockNumber(blockchainQueries, protocolSchedule),
new EthBlobBaseFee(blockchainQueries.getBlockchain(), protocolSchedule));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* 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.ethereum.api.jsonrpc.internal.methods;

import static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryBlockchain;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockDataGenerator;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.evm.gascalculator.CancunGasCalculator;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.evm.gascalculator.ShanghaiGasCalculator;

import java.util.Optional;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class EthBlobBaseFeeTest {
private final BlockDataGenerator blockDataGenerator = new BlockDataGenerator();
private MutableBlockchain blockchain;
private EthBlobBaseFee method;
private ProtocolSchedule protocolSchedule;

@BeforeEach
public void setUp() {
protocolSchedule = mock(ProtocolSchedule.class);
Block genesisBlock = blockDataGenerator.genesisBlock();
blockchain = createInMemoryBlockchain(genesisBlock);
blockDataGenerator
.blockSequence(genesisBlock, 10)
.forEach(block -> blockchain.appendBlock(block, blockDataGenerator.receipts(block)));
method = new EthBlobBaseFee(blockchain, protocolSchedule);
}

/** Tests that the method returns the expected blob base fee */
@Test
public void shouldReturnBlobBaseFee() {
configureProtocolSpec(FeeMarket.cancun(5, Optional.empty()), new CancunGasCalculator());
assertThat(requestBlobBaseFee().getResult()).isEqualTo("0x1");
}

/** Tests that the method returns zero for forks that do not support blob transactions */
@Test
public void shouldReturnZeroForNonBlobForks() {
configureProtocolSpec(FeeMarket.london(5, Optional.empty()), new ShanghaiGasCalculator());
assertThat(requestBlobBaseFee().getResult()).isEqualTo("0x0");
}

private void configureProtocolSpec(
final BaseFeeMarket feeMarket, final GasCalculator gasCalculator) {
ProtocolSpec spec = mock(ProtocolSpec.class);
when(spec.getFeeMarket()).thenReturn(feeMarket);
when(spec.getGasCalculator()).thenReturn(gasCalculator);
when(protocolSchedule.getForNextBlockHeader(
blockchain.getChainHeadHeader(), blockchain.getChainHeadHeader().getTimestamp()))
.thenReturn(spec);
}

private JsonRpcSuccessResponse requestBlobBaseFee() {
return (JsonRpcSuccessResponse)
method.response(
new JsonRpcRequestContext(new JsonRpcRequest("2.0", "eth_blobBaseFee", null)));
}
}

0 comments on commit bc2eed1

Please sign in to comment.