Skip to content

Commit

Permalink
prague fee market for blob gas (#8064)
Browse files Browse the repository at this point in the history
* prague fee market for blob gas

Signed-off-by: garyschulte <[email protected]>

* Fix wiring and unit test

Signed-off-by: Simon Dudley <[email protected]>

---------

Signed-off-by: garyschulte <[email protected]>
Signed-off-by: Simon Dudley <[email protected]>
Co-authored-by: Simon Dudley <[email protected]>
  • Loading branch information
garyschulte and siladu authored Dec 21, 2024
1 parent b3b33da commit 2909ea4
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
Expand Down Expand Up @@ -323,8 +322,7 @@ private void mockBlockWithBlobTransaction(final Hash blockHash, final long block
}

private void mockProtocolSpec(final BlockHeader blockHeader) {
FeeMarket feeMarket = mock(CancunFeeMarket.class);
when(feeMarket.blobGasPricePerGas(any())).thenCallRealMethod();
FeeMarket feeMarket = new CancunFeeMarket(0, Optional.empty());
ProtocolSpec spec = mock(ProtocolSpec.class);
when(spec.getFeeMarket()).thenReturn(feeMarket);
when(spec.getGasCalculator()).thenReturn(new CancunGasCalculator());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,18 @@ static ProtocolSpecBuilder pragueDefinition(
final java.util.function.Supplier<GasCalculator> pragueGasCalcSupplier =
() -> new PragueGasCalculator(pragueBlobSchedule.getTarget());

final BaseFeeMarket pragueFeeMarket;
if (genesisConfigOptions.isZeroBaseFee()) {
pragueFeeMarket = FeeMarket.zeroBaseFee(londonForkBlockNumber);
} else if (genesisConfigOptions.isFixedBaseFee()) {
pragueFeeMarket =
FeeMarket.fixedBaseFee(
londonForkBlockNumber, miningConfiguration.getMinTransactionGasPrice());
} else {
pragueFeeMarket =
FeeMarket.prague(londonForkBlockNumber, genesisConfigOptions.getBaseFeePerGas());
}

return cancunDefinition(
chainId,
enableRevertReason,
Expand All @@ -823,6 +835,7 @@ static ProtocolSpecBuilder pragueDefinition(
miningConfiguration,
isParallelTxProcessingEnabled,
metricsSystem)
.feeMarket(pragueFeeMarket)
.gasCalculator(pragueGasCalcSupplier)
// EIP-7840 Blob schedule | EIP-7691 6/9 blob increase
.gasLimitCalculatorBuilder(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

public class CancunFeeMarket extends LondonFeeMarket {
private static final Logger LOG = LoggerFactory.getLogger(CancunFeeMarket.class);
private static final BigInteger BLOB_GAS_PRICE = BigInteger.ONE;
protected static final BigInteger BLOB_GAS_PRICE = BigInteger.ONE;
private static final BigInteger BLOB_GAS_PRICE_UPDATE_FRACTION = BigInteger.valueOf(3338477);

public CancunFeeMarket(
Expand Down Expand Up @@ -53,7 +53,7 @@ public Wei blobGasPricePerGas(final BlobGas excessBlobGas) {
return blobGasPrice;
}

private BigInteger fakeExponential(
protected BigInteger fakeExponential(
final BigInteger factor, final BigInteger numerator, final BigInteger denominator) {
int i = 1;
BigInteger output = BigInteger.ZERO;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ static BaseFeeMarket cancun(
return new CancunFeeMarket(londonForkBlockNumber, baseFeePerGasOverride);
}

static BaseFeeMarket prague(
final long londonForkBlockNumber, final Optional<Wei> baseFeePerGasOverride) {
return new PragueFeeMarket(londonForkBlockNumber, baseFeePerGasOverride);
}

static BaseFeeMarket zeroBaseFee(final long londonForkBlockNumber) {
return new ZeroBaseFeeMarket(londonForkBlockNumber);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright contributors to 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.ethereum.mainnet.feemarket;

import org.hyperledger.besu.datatypes.BlobGas;
import org.hyperledger.besu.datatypes.Wei;

import java.math.BigInteger;
import java.util.Optional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class PragueFeeMarket extends CancunFeeMarket {
private static final BigInteger BLOB_BASE_FEE_UPDATE_FRACTION_ELECTRA =
BigInteger.valueOf(5007716);
private static final Logger LOG = LoggerFactory.getLogger(PragueFeeMarket.class);

public PragueFeeMarket(
final long londonForkBlockNumber, final Optional<Wei> baseFeePerGasOverride) {
super(londonForkBlockNumber, baseFeePerGasOverride);
}

@Override
public Wei blobGasPricePerGas(final BlobGas excessBlobGas) {
final var blobGasPrice =
Wei.of(
fakeExponential(
BLOB_GAS_PRICE,
excessBlobGas.toBigInteger(),
BLOB_BASE_FEE_UPDATE_FRACTION_ELECTRA));
LOG.atTrace()
.setMessage("parentExcessBlobGas: {} blobGasPrice: {}")
.addArgument(excessBlobGas::toShortHexString)
.addArgument(blobGasPrice::toHexString)
.log();

return blobGasPrice;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* 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.ethereum.mainnet.feemarket;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.hyperledger.besu.datatypes.BlobGas;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import org.junit.jupiter.api.Test;

class PragueFeeMarketTest {

private static final int BLOB_GAS_PER_BLOB = 131072;

/**
* from: https://eips.ethereum.org/EIPS/eip-7691 The BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE value in
* this EIP is chosen as the mid-point between keeping the responsiveness to full blobs and no
* blobs constant:
*
* <p>full blobs: basefee increases by ~8.2% no blobs: basefee decreases by ~14.5%
*/
@Test
void dataPricePerGas() {
PragueFeeMarket pragueFeeMarket = new PragueFeeMarket(0, Optional.empty());
// when no excess blob gas, data price per gas is 1
assertEquals(1, pragueFeeMarket.blobGasPricePerGas(BlobGas.ZERO).getAsBigInteger().intValue());

record BlobGasPricing(long excess, long price) {}
List<BlobGasPricing> testVector = new ArrayList<>();

int numBlobs = 1;
long price = 1;
while (price <= 1000) {
price = blobGasPrice(BlobGas.of(numBlobs * BLOB_GAS_PER_BLOB));
var testCase = new BlobGasPricing(numBlobs * BLOB_GAS_PER_BLOB, price);
testVector.add(testCase);
numBlobs++;
}

testVector.stream()
.forEach(
blobGasPricing -> {
assertEquals(
blobGasPricing.price,
pragueFeeMarket
.blobGasPricePerGas(BlobGas.of(blobGasPricing.excess))
.getAsBigInteger()
.intValue());
});
}

private long blobGasPrice(final BlobGas excess) {
double dgufDenominator = 5007716;
double fakeExpo = excess.getValue().longValue() / dgufDenominator;
return (long) (1 * Math.exp(fakeExpo));
}
}

0 comments on commit 2909ea4

Please sign in to comment.