From 9ec859b73cfd0dfe6279e96d2c50f01154fe909e Mon Sep 17 00:00:00 2001 From: Ryan Schneider Date: Fri, 1 Mar 2024 19:21:36 -0800 Subject: [PATCH] eth/gasprice: Actually return the "next" blob base fee --- eth/gasprice/feehistory.go | 42 ++++++++++++++++++++++----------- eth/gasprice/feehistory_test.go | 9 ++++--- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/eth/gasprice/feehistory.go b/eth/gasprice/feehistory.go index 96266c5a15..f098cc5d13 100644 --- a/eth/gasprice/feehistory.go +++ b/eth/gasprice/feehistory.go @@ -51,10 +51,11 @@ const ( // blockFees represents a single block for processing type blockFees struct { // set by the caller - blockNumber uint64 - header *types.Header - block *types.Block // only set if reward percentiles are requested - receipts types.Receipts + blockNumber uint64 + header *types.Header + parentHeader *types.Header + block *types.Block // only set if reward percentiles are requested + receipts types.Receipts // filled by processBlock results processedFees err error @@ -67,11 +68,11 @@ type cacheKey struct { // processedFees contains the results of a processed block. type processedFees struct { - reward []*big.Int - baseFee, nextBaseFee *big.Int - gasUsedRatio float64 - blobGasUsedRatio float64 - blobBaseFee *big.Int + reward []*big.Int + baseFee, nextBaseFee *big.Int + gasUsedRatio float64 + blobGasUsedRatio float64 + blobBaseFee, nextBlobBaseFee *big.Int } // txGasAndReward is sorted in ascending order based on reward @@ -96,13 +97,21 @@ func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) { bf.results.gasUsedRatio = float64(bf.header.GasUsed) / float64(bf.header.GasLimit) bf.results.blobGasUsedRatio = 0.0 bf.results.blobBaseFee = new(big.Int) + + getBlobBaseFee := func(h *types.Header) *big.Int { + if h != nil && chainconfig.IsCancun(h.Number, h.Time) { + if excessBlobGas := h.ExcessBlobGas; excessBlobGas != nil { + return eip4844.CalcBlobFee(*excessBlobGas) + } + } + return new(big.Int) + } + bf.results.blobBaseFee = getBlobBaseFee(bf.parentHeader) + bf.results.nextBlobBaseFee = getBlobBaseFee(bf.header) if bf.header != nil && chainconfig.IsCancun(bf.header.Number, bf.header.Time) { if blobGasUsed := bf.header.BlobGasUsed; blobGasUsed != nil { bf.results.blobGasUsedRatio = float64(*blobGasUsed) / params.MaxBlobGasPerBlock } - if excessBlobGas := bf.header.ExcessBlobGas; excessBlobGas != nil { - bf.results.blobBaseFee = eip4844.CalcBlobFee(*excessBlobGas) - } } if len(percentiles) == 0 { // rewards were not requested, return null @@ -281,6 +290,7 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks uint64, unresolvedL if pendingBlock != nil && blockNumber >= pendingBlock.NumberU64() { fees.block, fees.receipts = pendingBlock, pendingReceipts fees.header = fees.block.Header() + fees.parentHeader, fees.err = oracle.backend.HeaderByNumber(ctx, rpc.BlockNumber(pendingBlock.NumberU64()-1)) oracle.processBlock(fees, rewardPercentiles) results <- fees } else { @@ -300,6 +310,9 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks uint64, unresolvedL fees.header, fees.err = oracle.backend.HeaderByNumber(ctx, rpc.BlockNumber(blockNumber)) } if fees.header != nil && fees.err == nil { + if blockNumber > 0 { + fees.parentHeader, fees.err = oracle.backend.HeaderByNumber(ctx, rpc.BlockNumber(blockNumber-1)) + } oracle.processBlock(fees, rewardPercentiles) if fees.err == nil { oracle.historyCache.Add(cacheKey, fees.results) @@ -317,7 +330,7 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks uint64, unresolvedL baseFee = make([]*big.Int, blocks+1) gasUsedRatio = make([]float64, blocks) blobGasUsedRatio = make([]float64, blocks) - blobBaseFee = make([]*big.Int, blocks) + blobBaseFee = make([]*big.Int, blocks+1) firstMissing = blocks ) for ; blocks > 0; blocks-- { @@ -328,7 +341,7 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks uint64, unresolvedL i := fees.blockNumber - oldestBlock if fees.results.baseFee != nil { reward[i], baseFee[i], baseFee[i+1], gasUsedRatio[i] = fees.results.reward, fees.results.baseFee, fees.results.nextBaseFee, fees.results.gasUsedRatio - blobGasUsedRatio[i], blobBaseFee[i] = fees.results.blobGasUsedRatio, fees.results.blobBaseFee + blobGasUsedRatio[i], blobBaseFee[i], blobBaseFee[i+1] = fees.results.blobGasUsedRatio, fees.results.blobBaseFee, fees.results.nextBlobBaseFee } else { // getting no block and no error means we are requesting into the future (might happen because of a reorg) if i < firstMissing { @@ -345,5 +358,6 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks uint64, unresolvedL reward = nil } baseFee, gasUsedRatio = baseFee[:firstMissing+1], gasUsedRatio[:firstMissing] + blobBaseFee, blobGasUsedRatio = blobBaseFee[:firstMissing+1], blobGasUsedRatio[:firstMissing] return new(big.Int).SetUint64(oldestBlock), reward, baseFee, gasUsedRatio, blobBaseFee, blobGasUsedRatio, nil } diff --git a/eth/gasprice/feehistory_test.go b/eth/gasprice/feehistory_test.go index cd1c13ceb1..42a2290b17 100644 --- a/eth/gasprice/feehistory_test.go +++ b/eth/gasprice/feehistory_test.go @@ -61,7 +61,7 @@ func TestFeeHistory(t *testing.T) { backend := newTestBackend(t, big.NewInt(16), c.pending, true) oracle := NewOracle(backend, config) - first, reward, baseFee, ratio, blobBaseFee, blobUsed, err := oracle.FeeHistory(context.Background(), c.count, c.last, c.percent) + first, reward, baseFee, ratio, blobBaseFee, blobRatio, err := oracle.FeeHistory(context.Background(), c.count, c.last, c.percent) backend.teardown() expReward := c.expCount if len(c.percent) == 0 { @@ -84,8 +84,11 @@ func TestFeeHistory(t *testing.T) { if len(ratio) != c.expCount { t.Fatalf("Test case %d: gasUsedRatio array length mismatch, want %d, got %d", i, c.expCount, len(ratio)) } - if len(blobBaseFee) != len(blobUsed) || len(blobBaseFee) != c.expCount { - t.Fatalf("Test case %d: blob arrays length mismatch, want %d, got %d and %d", i, c.expCount, len(blobBaseFee), len(blobUsed)) + if len(blobRatio) != c.expCount { + t.Fatalf("Test case %d: blobGasUsedRatio array length mismatch, want %d, got %d", i, c.expCount, len(blobRatio)) + } + if len(blobBaseFee) != len(baseFee) { + t.Fatalf("Test case %d: blobBaseFee array length mismatch, want %d, got %d", i, len(baseFee), len(blobBaseFee)) } if err != c.expErr && !errors.Is(err, c.expErr) { t.Fatalf("Test case %d: error mismatch, want %v, got %v", i, c.expErr, err)