#!/usr/bin/env python # coding: utf-8 # # Eviction policy # # We look at two different rules to evict transactions that are in the transaction pool. # # ## Fixed band # # The rule is governed by a parameter `mu >= 0`. # # > Evict iff `(1-mu) * basefee > fee_cap` # # - For `mu = 0`, we evict as soon as `basefee` is above `fee_cap`. # # - If this is too strong, we can set `mu = 0.1` to tolerate fee caps within a 10% lower band of basefee. For instance, if `basefee = 10` and `mu = 0.1`, all transactions with fee cap greater than 9 are kept in the pool. # # ## Trend-picker # # We modify the rule above with a parameter increasing or decreasing the tolerance based on the current basefee trend. # # > Evict iff `(1+delta) * (1-mu) * basefee > fee_cap` # # `delta` is computed from recent basefees. `delta` should be close to zero when basefee is stable, positive when basefee trends upwards and negative when basefee trends downwards. We suggest # # ``` # delta = (basefee - moving_average(basefees, 10)) / basefee # ``` # # where `moving_average(basefees, 10)` returns the average basefee over the last 10 blocks. We divide by `basefee` to normalise the rule (same behaviour at 1 Gwei basefee and at 100 Gwei basefee). # # ### Stable basefee # # We work out some numbers when basefee is overall stable, yet noisy. In the extreme case, a full block is mined, followed by an empty block, followed by a full block etc. In this case, basefee is either increased by 12.5% or decreased by 12.5%. # In[1]: basefee = 10 basefees = [basefee] for i in range(10): basefee = basefee * (1 + 0.125 * ((-1) ** i)) basefees += [basefee] print(basefees) # In[2]: moving_averages = [] for i in range(5): moving_averages += [sum(basefees[i:(5+i)]) / 5] moving_averages # In[3]: deltas = [(basefees[i+6] - moving_averages[i])/basefees[i+6] for i in range(5)] deltas # We see that deltas are close to 0, albeit noisy. What is the tolerance of the policy? # In[4]: mu = 0.1 band_sizes = [(1+d) * (1-mu) for d in deltas] band_sizes # We end up keeping transactions with fee caps larger than ~91% of basefee. # ### Increasing basefee # # In this case, full blocks are mined one after the other. Basefee increases by 12.5% each step. # In[5]: basefee = 10 basefees = [basefee] for i in range(10): basefee = basefee * (1 + 0.125) basefees += [basefee] print(basefees) # In[6]: moving_averages = [] for i in range(5): moving_averages += [sum(basefees[i:(5+i)]) / 5] moving_averages # In[7]: deltas = [(basefees[i+6] - moving_averages[i])/basefees[i+6] for i in range(5)] deltas # In[8]: mu = 0.1 band_sizes = [(1+d) * (1-mu) for d in deltas] band_sizes # This is the maximum value `delta` can achieve. With `mu = 0.1`, this implies evicting all transactions with fee cap smaller than 123% of the current basefee. In particular, we evict transactions that have fee cap greater than the current basefee, if their fee cap is smaller than `1.23 * basefee`. This may be rationalised by the intuition that should basefee increase at this speed in a sustained manner, there are plenty more transactions with fee caps above `1.23 * basefee`, so we are only evicting transactions that have posted smaller fee caps than these. # If we are unhappy with throwing away currently valid transactions (even if they are likely dominated by higer fee cap transactions), we can also use the eviction rule # # > Evict iff `min((1+delta) * (1-mu), 1) * basefee > fee_cap`