mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 02:40:45 +00:00
core/txpool/blobpool: update blobpool eviction policy
Previously, blobpool eviction priority did not differentiate well transactions that are close to the basefee limit and transactions that are way under the limit. Here we improve this differentiation, giving more priority to transactions that are closer to the current base fee and/or blob fee, thus potentially includable in a shorter time. Signed-off-by: Csaba Kiraly <csaba.kiraly@gmail.com>
This commit is contained in:
parent
ba9d3548d4
commit
c376651c42
3 changed files with 32 additions and 34 deletions
|
|
@ -281,47 +281,48 @@ func newBlobTxMeta(id uint64, size uint64, storageSize uint32, tx *types.Transac
|
||||||
// solve after every block.
|
// solve after every block.
|
||||||
//
|
//
|
||||||
// - The first observation is that comparing 1559 base fees or 4844 blob fees
|
// - The first observation is that comparing 1559 base fees or 4844 blob fees
|
||||||
// needs to happen in the context of their dynamism. Since these fees jump
|
// needs to happen in the context of their dynamism. Since base fees are
|
||||||
// up or down in ~1.125 multipliers (at max) across blocks, comparing fees
|
// adjusted continuously and fluctuate, and we want to optimize for effective
|
||||||
// in two transactions should be based on log1.125(fee) to eliminate noise.
|
// miner fees, it is better to disregard small base fee cap differences.
|
||||||
|
// Instead of considering the exact fee cap values, we should group
|
||||||
|
// transactions into buckets based on fee cap values, allowing us to use
|
||||||
|
// the miner tip meaningfully as a splitter inside a bucket.
|
||||||
//
|
//
|
||||||
// - The second observation is that the basefee and blobfee move independently,
|
// To create these buckets, rather than looking at the absolute fee
|
||||||
// so there's no way to split mixed txs on their own (A has higher base fee,
|
// differences, the useful metric is the max time it can take to exceed the
|
||||||
// B has higher blob fee). Rather than look at the absolute fees, the useful
|
// transaction's fee caps. Base fee changes are multiplicative, so we use a
|
||||||
// metric is the max time it can take to exceed the transaction's fee caps.
|
// logarithmic scale. Fees jumps up or down in ~1.125 multipliers at max
|
||||||
|
// across blocks, so we use log1.125(fee) and rounding to eliminate noise.
|
||||||
// Specifically, we're interested in the number of jumps needed to go from
|
// Specifically, we're interested in the number of jumps needed to go from
|
||||||
// the current fee to the transaction's cap:
|
// the current fee to the transaction's cap:
|
||||||
//
|
//
|
||||||
// jumps = log1.125(txfee) - log1.125(basefee)
|
// jumps = floor(log1.125(txfee) - log1.125(basefee))
|
||||||
|
|
||||||
|
// - The second observation is that when ranking executable blob txs, it
|
||||||
|
// does not make sense to grant a later eviction priority to txs with high
|
||||||
|
// fee caps since it could enable pool wars. As such, any positive priority
|
||||||
|
// will be grouped together.
|
||||||
//
|
//
|
||||||
// - The third observation is that the base fee tends to hover around rather
|
// priority = min(jumps, 0)
|
||||||
// than swing wildly. The number of jumps needed from the current fee starts
|
|
||||||
// to get less relevant the higher it is. To remove the noise here too, the
|
// - The third observation is that the basefee and blobfee move independently,
|
||||||
// pool will use log(jumps) as the delta for comparing transactions.
|
// so there's no way to split mixed txs on their own (A has higher base fee,
|
||||||
|
// B has higher blob fee).
|
||||||
//
|
//
|
||||||
// delta = sign(jumps) * log(abs(jumps))
|
// To establish a total order, we need to reduce the dimensionality of the
|
||||||
//
|
|
||||||
// - To establish a total order, we need to reduce the dimensionality of the
|
|
||||||
// two base fees (log jumps) to a single value. The interesting aspect from
|
// two base fees (log jumps) to a single value. The interesting aspect from
|
||||||
// the pool's perspective is how fast will a tx get executable (fees going
|
// the pool's perspective is how fast will a tx get executable (fees going
|
||||||
// down, crossing the smaller negative jump counter) or non-executable (fees
|
// down, crossing the smaller negative jump counter) or non-executable (fees
|
||||||
// going up, crossing the smaller positive jump counter). As such, the pool
|
// going up, crossing the smaller positive jump counter). As such, the pool
|
||||||
// cares only about the min of the two delta values for eviction priority.
|
// cares only about the min of the two delta values for eviction priority.
|
||||||
//
|
//
|
||||||
// priority = min(deltaBasefee, deltaBlobfee)
|
// priority = min(deltaBasefee, deltaBlobfee, 0)
|
||||||
//
|
//
|
||||||
// - The above very aggressive dimensionality and noise reduction should result
|
// - The above very aggressive dimensionality and noise reduction should result
|
||||||
// in transaction being grouped into a small number of buckets, the further
|
// in transaction being grouped into a small number of buckets, the further
|
||||||
// the fees the larger the buckets. This is good because it allows us to use
|
// the fees the larger the buckets. This is good because it allows us to use
|
||||||
// the miner tip meaningfully as a splitter.
|
// the miner tip meaningfully as a splitter.
|
||||||
//
|
//
|
||||||
// - For the scenario where the pool does not contain non-executable blob txs
|
|
||||||
// anymore, it does not make sense to grant a later eviction priority to txs
|
|
||||||
// with high fee caps since it could enable pool wars. As such, any positive
|
|
||||||
// priority will be grouped together.
|
|
||||||
//
|
|
||||||
// priority = min(deltaBasefee, deltaBlobfee, 0)
|
|
||||||
//
|
|
||||||
// Optimisation tradeoffs:
|
// Optimisation tradeoffs:
|
||||||
//
|
//
|
||||||
// - Eviction relies on 3 fee minimums per account (exec tip, exec cap and blob
|
// - Eviction relies on 3 fee minimums per account (exec tip, exec cap and blob
|
||||||
|
|
|
||||||
|
|
@ -43,11 +43,8 @@ func evictionPriority(basefeeJumps float64, txBasefeeJumps, blobfeeJumps, txBlob
|
||||||
// described in the BlobPool docs for a single fee component.
|
// described in the BlobPool docs for a single fee component.
|
||||||
func evictionPriority1D(basefeeJumps float64, txfeeJumps float64) int {
|
func evictionPriority1D(basefeeJumps float64, txfeeJumps float64) int {
|
||||||
jumps := txfeeJumps - basefeeJumps
|
jumps := txfeeJumps - basefeeJumps
|
||||||
if int(jumps) == 0 {
|
if jumps <= 0 {
|
||||||
return 0 // can't log2 0
|
return int(math.Floor(jumps))
|
||||||
}
|
|
||||||
if jumps < 0 {
|
|
||||||
return -intLog2(uint(-math.Floor(jumps)))
|
|
||||||
}
|
}
|
||||||
return intLog2(uint(math.Ceil(jumps)))
|
return intLog2(uint(math.Ceil(jumps)))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,12 +30,12 @@ func TestPriorityCalculation(t *testing.T) {
|
||||||
txfee uint64
|
txfee uint64
|
||||||
result int
|
result int
|
||||||
}{
|
}{
|
||||||
{basefee: 7, txfee: 10, result: 2}, // 3.02 jumps, 4 ceil, 2 log2
|
{basefee: 7, txfee: 10, result: 2}, // 3.02 jumps, 4 ceil, 2 log2
|
||||||
{basefee: 17_200_000_000, txfee: 17_200_000_000, result: 0}, // 0 jumps, special case 0 log2
|
{basefee: 17_200_000_000, txfee: 17_200_000_000, result: 0}, // 0 jumps, special case 0 log2
|
||||||
{basefee: 9_853_941_692, txfee: 11_085_092_510, result: 0}, // 0.99 jumps, 1 ceil, 0 log2
|
{basefee: 9_853_941_692, txfee: 11_085_092_510, result: 0}, // 0.99 jumps, 1 ceil, 0 log2
|
||||||
{basefee: 11_544_106_391, txfee: 10_356_781_100, result: 0}, // -0.92 jumps, -1 floor, 0 log2
|
{basefee: 11_544_106_391, txfee: 10_356_781_100, result: -1}, // -0.92 jumps, -1 floor
|
||||||
{basefee: 17_200_000_000, txfee: 7, result: -7}, // -183.57 jumps, -184 floor, -7 log2
|
{basefee: 17_200_000_000, txfee: 7, result: -184}, // -183.57 jumps, -184 floor
|
||||||
{basefee: 7, txfee: 17_200_000_000, result: 7}, // 183.57 jumps, 184 ceil, 7 log2
|
{basefee: 7, txfee: 17_200_000_000, result: 7}, // 183.57 jumps, 184 ceil, 7 log2
|
||||||
}
|
}
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
var (
|
var (
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue