Skip to content

Commit d482b2f

Browse files
authored
add non congested gas fee to fee history (#1163)
* add non congested gas fee to fee history * address comment
1 parent d6b4c96 commit d482b2f

File tree

1 file changed

+34
-11
lines changed

1 file changed

+34
-11
lines changed

eth/gasprice/feehistory.go

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func (s sortGasAndReward) Less(i, j int) bool {
8484
// processBlock takes a blockFees structure with the blockNumber, the header and optionally
8585
// the block field filled in, retrieves the block from the backend if not present yet and
8686
// fills in the rest of the fields.
87-
func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) {
87+
func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64, nonCongestedPrice *big.Int) {
8888
chainconfig := oracle.backend.ChainConfig()
8989
if bf.results.baseFee = bf.header.BaseFee; bf.results.baseFee == nil {
9090
bf.results.baseFee = new(big.Int)
@@ -121,7 +121,12 @@ func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) {
121121

122122
sorter := make(sortGasAndReward, len(bf.block.Transactions()))
123123
for i, tx := range bf.block.Transactions() {
124-
reward, _ := tx.EffectiveGasTip(bf.block.BaseFee())
124+
var reward *big.Int
125+
if nonCongestedPrice != nil {
126+
reward = nonCongestedPrice
127+
} else {
128+
reward, _ = tx.EffectiveGasTip(bf.block.BaseFee())
129+
}
125130
sorter[i] = txGasAndReward{gasUsed: bf.receipts[i].GasUsed, reward: reward}
126131
}
127132
sort.Sort(sorter)
@@ -144,51 +149,54 @@ func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) {
144149
// also returned if requested and available.
145150
// Note: an error is only returned if retrieving the head header has failed. If there are no
146151
// retrievable blocks in the specified range then zero block count is returned with no error.
147-
func (oracle *Oracle) resolveBlockRange(ctx context.Context, lastBlock rpc.BlockNumber, blocks int) (*types.Block, []*types.Receipt, uint64, int, error) {
152+
func (oracle *Oracle) resolveBlockRange(ctx context.Context, lastBlock rpc.BlockNumber, blocks int) (*types.Block, []*types.Receipt, uint64, int, *types.Header, error) {
148153
var (
149154
headBlock rpc.BlockNumber
150155
pendingBlock *types.Block
151156
pendingReceipts types.Receipts
157+
headHeader *types.Header
152158
)
153159
// query either pending block or head header and set headBlock
154160
if lastBlock == rpc.PendingBlockNumber {
155161
if pendingBlock, pendingReceipts = oracle.backend.PendingBlockAndReceipts(); pendingBlock != nil {
156162
lastBlock = rpc.BlockNumber(pendingBlock.NumberU64())
157163
headBlock = lastBlock - 1
164+
headHeader = pendingBlock.Header()
158165
} else {
159166
// pending block not supported by backend, process until latest block
160167
lastBlock = rpc.LatestBlockNumber
161168
blocks--
162169
if blocks == 0 {
163-
return nil, nil, 0, 0, nil
170+
return nil, nil, 0, 0, nil, nil
164171
}
165172
}
166173
}
167174
if pendingBlock == nil {
168175
// if pending block is not fetched then we retrieve the head header to get the head block number
169176
if latestHeader, err := oracle.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber); err == nil {
170177
headBlock = rpc.BlockNumber(latestHeader.Number.Uint64())
178+
headHeader = latestHeader
171179
} else {
172-
return nil, nil, 0, 0, err
180+
return nil, nil, 0, 0, nil, err
173181
}
174182
}
175183
if lastBlock == rpc.LatestBlockNumber {
176184
lastBlock = headBlock
177185
} else if pendingBlock == nil && lastBlock > headBlock {
178-
return nil, nil, 0, 0, fmt.Errorf("%w: requested %d, head %d", errRequestBeyondHead, lastBlock, headBlock)
186+
return nil, nil, 0, 0, nil, fmt.Errorf("%w: requested %d, head %d", errRequestBeyondHead, lastBlock, headBlock)
179187
}
180188
if lastBlock == rpc.FinalizedBlockNumber {
181189
if latestFinalizedHeader, err := oracle.backend.HeaderByNumber(ctx, rpc.FinalizedBlockNumber); err == nil {
182190
lastBlock = rpc.BlockNumber(latestFinalizedHeader.Number.Uint64())
183191
} else {
184-
return nil, nil, 0, 0, err
192+
return nil, nil, 0, 0, nil, err
185193
}
186194
}
187195
// ensure not trying to retrieve before genesis
188196
if rpc.BlockNumber(blocks) > lastBlock+1 {
189197
blocks = int(lastBlock + 1)
190198
}
191-
return pendingBlock, pendingReceipts, uint64(lastBlock), blocks, nil
199+
return pendingBlock, pendingReceipts, uint64(lastBlock), blocks, headHeader, nil
192200
}
193201

194202
// FeeHistory returns data relevant for fee estimation based on the specified range of blocks.
@@ -230,12 +238,26 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks int, unresolvedLast
230238
pendingReceipts []*types.Receipt
231239
err error
232240
)
233-
pendingBlock, pendingReceipts, lastBlock, blocks, err := oracle.resolveBlockRange(ctx, unresolvedLastBlock, blocks)
241+
pendingBlock, pendingReceipts, lastBlock, blocks, headHeader, err := oracle.resolveBlockRange(ctx, unresolvedLastBlock, blocks)
234242
if err != nil || blocks == 0 {
235243
return common.Big0, nil, nil, nil, err
236244
}
237245
oldestBlock := lastBlock + 1 - uint64(blocks)
238246

247+
// If pending txs are less than oracle.congestedThreshold, we consider the network to be non-congested and suggest
248+
// a minimal tip cap. This is to prevent users from overpaying for gas when the network is not congested and a few
249+
// high-priced txs are causing the suggested tip cap to be high.
250+
var nonCongestedPrice *big.Int
251+
pendingTxCount, _ := oracle.backend.StatsWithMinBaseFee(headHeader.BaseFee)
252+
if pendingTxCount < oracle.congestedThreshold {
253+
// Before Curie (EIP-1559), we need to return the total suggested gas price. After Curie we return defaultGasTipCap wei as the tip cap,
254+
// as the base fee is set separately or added manually for legacy transactions.
255+
nonCongestedPrice = oracle.defaultGasTipCap
256+
if !oracle.backend.ChainConfig().IsCurie(headHeader.Number) {
257+
nonCongestedPrice = oracle.defaultBasePrice
258+
}
259+
}
260+
239261
var (
240262
next = oldestBlock
241263
results = make(chan *blockFees, blocks)
@@ -244,6 +266,7 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks int, unresolvedLast
244266
for i, p := range rewardPercentiles {
245267
binary.LittleEndian.PutUint64(percentileKey[i*8:(i+1)*8], math.Float64bits(p))
246268
}
269+
247270
for i := 0; i < maxBlockFetchers && i < blocks; i++ {
248271
go func() {
249272
for {
@@ -257,7 +280,7 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks int, unresolvedLast
257280
if pendingBlock != nil && blockNumber >= pendingBlock.NumberU64() {
258281
fees.block, fees.receipts = pendingBlock, pendingReceipts
259282
fees.header = fees.block.Header()
260-
oracle.processBlock(fees, rewardPercentiles)
283+
oracle.processBlock(fees, rewardPercentiles, nonCongestedPrice)
261284
results <- fees
262285
} else {
263286
cacheKey := struct {
@@ -279,7 +302,7 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks int, unresolvedLast
279302
fees.header, fees.err = oracle.backend.HeaderByNumber(ctx, rpc.BlockNumber(blockNumber))
280303
}
281304
if fees.header != nil && fees.err == nil {
282-
oracle.processBlock(fees, rewardPercentiles)
305+
oracle.processBlock(fees, rewardPercentiles, nonCongestedPrice)
283306
if fees.err == nil {
284307
oracle.historyCache.Add(cacheKey, fees.results)
285308
}

0 commit comments

Comments
 (0)