I will unfortunately have to present remotely; it’s too close to EthCapetown for me to fly in personally. But will be very happy to do be around on call for as long as needed.
Great, remote is fine. Is this the best place to work out logistics? or I can use email / telegram / whatever works.
We will need to know your time zone to schedule you at a reasonable time.
I love this proposal! I am a non-developer who has performed several thousand transactions in the last few months, and paid gas prices ranging from 1 to 40 Gwei via metamask. The current system actually works fairly well for me, since I have become an expert in picking the correct gas price, but I would like to not spend so much time gaming the gas prices.
Rather than adjusting the MINFEE by 1/8 in each block, is there a reason we can’t adjust it once a day to remove fluctuation even more? I would like to see a target of 50 Billion gas per day rather than 8 million per block, and triple the max size of each block to 24 million gas (uncles allowing). That way if a big ICO or surge of spam hits, we could see 100 Billion in gas for 24 hours, and then MINFEE increases once every 6200 blocks (like Bitcoin-style difficulty adjustments) until the daily gas usage falls below the target…at which point it slowly starts coming back down. This would have the nice effect of doubling current transaction capacity during busy periods while keeping the state size growth where it is now.
If anyone has a super urgent transaction, they could pay 2x MINFEE to (nearly) guarantee it in the next block. Metamask could then simplify the choice of fee to Normal and Fast (2x).
Exciting research overall and the big picture is crystal clear, but from what I understand the choice of the actual update rule for dynamic pricing is not justified very well. For this specific proposed formula, I have an attack in which a small number of users with only 10% of transaction volume can halve the price in less than 1000 blocks only by a particular timing for broadcasting their transactions.
Replied on the Zcash thread, copying my replies here:
I think I see the flaw in your attack strategy. Your attack basically says that the attacker (with 10% of all transactions) concentrates their transactions in every tenth block, so nine blocks out of ten, the attacker’s share is empty and the block size is 90% of the target, and the tenth time the attacker sends all their transactions so the block size is 190% of the target. This means that gas usage adjusts down by 1.25% nine blocks out of ten and adjusts up 11.25% the tenth time, but because of (x-a)*(x+a) < x**2
inequalities, this leads to a slight decrease on average (0.9875 ** 9 * 1.1125 ~= 0.9934
per 10-block period). Applying this 100 times, we get the observed 50% decrease. So it is true that it’s possible to send the same transaction volume with slightly different consequences to demand, but this ignores the fact that demand adjusts with fees, and once the fee drops a few percent others will come in and the equilibrium re-established. All that this means is that in equilibrium average usage will be about 0.5% higher than the target; not a big deal.
That said, if we want to eliminate this issue entirely, we can do that by replacing minfee *= (1 + excess * adjSpeed)
with minfee *= e ** (excess * adjSpeed)
. Doing exponentiation in consensus is hard, but if we apply a quadratic Taylor approximation e ** x = 1 + x + x**2 / 2
, so we do minfee *= (1 + excess * adjSpeed + (excess * adjSpeed) ** 2 / 2)
, then the discrepancy drops from 1 - 0.9934 to 1 - 0.99978. I’m not sure if it’s worth the extra complexity, I think either way works fine.
Users are paying for the burden which the previous users put on the network rather than their own
This is intentional for incentive compatibility. It’s a common technique in game theory for the price that a user pays to be explicitly only based on other users’ activity, so that incentive-compatibility for the user can be proven trivially as a simple matter of “if the price is favorable the user gets it, otherwise the user does not”. Otherwise, a user’s “real price” is higher than the “set price” because a user has to take into account the fact that their own transaction pushes up the real price for themselves.
Replied on the Zcash thread, copying my replies here:
Otherwise, a user’s “real price” is higher than the “set price” because a user has to take into account the fact that their own transaction pushes up the real price for themselves.
Yes, I agree with your observation. However, I think this can actually be a good point and should be exploited because it incentivizes a user to avoid executing a lot of transactions in a single block. This is similar to the problem of liquifying a large volume of some asset in game theory, in which whenever you sell some amount the price goes down, and as a result, you are incentivized to sell little by little. I think the same mechanism design helps to avoid network congestion.
To be more specific, I have already mentioned the paper “Optimal Execution of Portfolio Transactions” in which the authors prove that if we have a very similar additive update formula, the optimal strategy is to execute transactions over a long period of time. Maybe we can use the same formula in here.
That said, if we want to eliminate this issue entirely, we can do that by replacing
minfee *= (1 + excess * adjSpeed)
withminfee *= e ** (excess * adjSpeed)
.
If I rewrite your formula as log(minfee) += excess * adjSpeed
your alternative suggestion is just to have the same additive update rule and then exponentiate it to get minfee
. As I said in the previous comment the additive framework is well-known in economics but why the exponential? In other words, suppose that minfee += excess * adjSpeed
, and then we charge everyone a fee of f(minfee)
. f
could be the identity function, an affine mapping, or any other positive increasing function including the exponential function, but I am not sure why exponential seems like a canonical choice to you?
This is intentional for incentive compatibility. It’s a common technique in game theory for the price that a user pays to be explicitly only based on other users’ activity, so that incentive-compatibility for the user can be proven trivially as a simple matter of “if the price is favorable the user gets it, otherwise the user does not”.
Even in the new settings corrected by the exponential or additive formula, I still believe that users should also be charged for their own transactions as well as the aggregated previous usage. Today, I was reading about the gas token and any such smart contract exploiting storage refund in Ethereum can be used for hoarding which is immediately profitable if the gas price you pay is independent of the gas cost of your smart contract.
What is to stop miners constantly reducing MINFEE to 0, at which point we’re back to a pure auction-based system? The transaction pool cannot be considered a valid measure of network capacity (given that it’s variable across nodes) so it would have to come down to block capacity. Why wouldn’t miners mine empty blocks until MINFEE is 0, then only fill blocks half-full to keep it there?
I have tried to run a simple model to see how MIN_FEE
would look like for the existing history of blocks and transactions. Assuming that TARGET_GAS_USED
is equal to the half of the block’s gas limit. The first thing I noticed is that formula for MIN_FEE
gets stuck at 0 if it ever gets there. Any suggestions?
Vitalik suggested introducing a minimum in the MIN_FEE
formula, like 1000 wei. It worked, until the around the block 4.13m, after which the MIN_FEE
started to run away into infinity, and by the block 4.7m the numbers were 1 console page long
EDIT: I know that the clamping probably needs to be applied, but how exactly do it? Also, I agree with other comments that the determination of MIN_FEE
needs to be driven by the protocol itself and not “voted” up and down by the miners.
Here is the Vitalik’s presentation on the matter: https://youtu.be/HaT-BIzWSew?t=4708
And here is my proposed amendment (I am planning to put it in text quite soon), just after Vitalik’s presentation: https://youtu.be/HaT-BIzWSew?t=6601
Because with an exponential function the rate of change in percentage terms does not depend on the current fee level. This seems like a natural property to have, especially since it means that the fee can adjust to unexpectedly huge spikes in logarithmic time rather than linear time. If we don’t care about this, then a linearly adjusted min fee (eg. max 0.25 gwei adjustment per block) could work too.
Vitalik suggested introducing a minimum in the
MIN_FEE
formula, like 1000 wei. It worked, until the around the block 4.13m, after which theMIN_FEE
started to run away into infinity, and by the block 4.7m the numbers were 1 console page long
So this is why you can’t test the min fee formula without actually using it on a blockchain. The feedback mechanism critically depends on the fact that if the fee shoots up demand decreases.
However, I think this can actually be a good point and should be exploited because it incentivizes a user to avoid executing a lot of transactions in a single block.
If the total volume in one block ends up exceeding the gas limit, then it already becomes more expensive for you, because you have to outbid other people’s fee premiums. If it does not, then as I mentioned in my presentation, there’s basically negligible social harm from having one block with 12 million gas followed by a block with 4 million gas compared to two blocks with 8 million gas, so what’s the problem?
I think the problem is that the people in the next block are paying much more because of your transactions while outbidding the others in the current block should not be that much costly.
@mcdee, an excellent observation. The situation is worse than what you described as miners do not have to fill blocks half-full to keep it there. They can fill them up, and once the price is zero, it always remains zero. I think that there should be no incentive for miners to roll back into the auction-based system. My proposal is a sliding median price auction for the premiums to avoid overpayments instead of the first price auction. You can read more details in here.
Continuing my previous discussion about the choice of the update function f
, the additive formula does not have this problem as the price can always recover from zero.
My proposal: Set a minimum value of at least 1 wei to MINFEE
, PARENT_MINFEE
, and block.gas_used
.
delta = block.gas_used - TARGET_GASUSED
TARGET_GASUSED = 8,000,000
MINFEE_MAX_CHANGE_DENOMINATOR = 8
There is also way to simplify the MINFEE
formula:
MINFEE = PARENT_MINFEE + PARENT_MINFEE * delta // TARGET_GASUSED // MINFEE_MAX_CHANGE_DENOMINATOR
For the rest of this comment, I will be using abbreviated variable names:
MF = MINFEE
MF_P = PARENT_MINFEE
MF_MCD = MINFEE_MAX_CHANGE_DENOMINATOR
GU_B = block.gas_used
GU_T = TARGET_GASUSED
delta = GU_B - GU_T
Note: I’m also using /
for division instead of //
- Substitute original formula with new variable names
MF = MF_P + MF_P * delta / GU_T / MF_MCD
- Separate
MF_P
MF = MF_P * (1 + delta / GU_T / MF_MCD)
- Instead of dividing by
MF_MCD
, multiply by the reciprocal
MF = MF_P * (1 + (delta / GU_T) * (1 / MF_MCD))
- Substitute in the variables for
delta
MF = MF_P * (1 + ((GU_B - GU_T) / GU_T) * (1 / MF_MCD))
- Separate the delta variables from the numerator and divide both delta variables
by the same denominator
MF = MF_P * (1 + ((GU_B / GU_T) - (GU_T / GU_T)) * (1 / MF_MCD))
-
GU_T / GU_T
== 1, so replaceGU_T / GU_T
with1
MF = MF_P * (1 + ((GU_B / GU_T) - 1) * (1 / MF_MCD))
- Multiply
1 / MF_MCD
with bothGU_B / GU_T
and-1
MF = MF_P * (1 + (GU_B / (GU_T * MF_MCD)) - (1 / MF_MCD))
- Replace the first
1
withMF_MCD / MF_MCD
MF = MF_P * ((MF_MCD / MF_MCD) + (GU_B / (GU_T * MF_MCD)) - (1 / MF_MCD))
- Since
MF_MCD / MF_MCD
and1 / MF_MCD
have the same denominator, we can combine the numerators
MF = MF_P * (((MF_MCD - 1) / MF_MCD) + (GU_B / (GU_T * MF_MCD)))
- Replace
MF_MCD
andGU_T
with their static values
MF = MF_P * (((8 - 1) / 8) + (GU_B / (8,000,000 * 8)))
- Simplify
MF = MF_P * (7 / 8) * (GU_B / 64,000,000)
MF = MF_P * ((7 * GU_B) / 512,000,000)
or
MF = MF_P * ((7 * GU_B) / (2^9 * 10^6))
My conclusion:
-
MINFEE
,PARENT_MINFEE
, andblock.gas_used
can never be equal to 0. - If
MINFEE
,PARENT_MINFEE
, orblock.gas_used
equal 0, all three variables
will equal 0.
Additional question:
- Can a bad actor to intentionally mine a block with 0 gas used?
They commonly do, yes.
They do, but not necessarily as a bad actor. If constructing a block full of transaction takes a long time, they first quickly construct an empty block, start mining it. Then, if constructing the block finishes and the empty block is still not mined, then they switch to the full block. If, however, the empty block is mined before the full block is constructed, they just publish the empty block. Makes economic sense
Seems like:
- What is the ideal adjustment formula?
- How to simulate and verify it?
Are good open questions to add as directives for the working group.
Another open question for me:
- Is the computation cost of verifying there is a miner-tip for a transaction enough to justify a miner even considering adding it?
My thinking so far is that it isn’t enough for one person to tip “enough”, but there have to be enough people tipping enough for the likelihood of any one transaction to have enough value for a miner to consider including any transactions.
- From a miner’s point of view, what is the Expected Value (in the sense of probability theory) of adding one transaction to my block?
- From a users view, what is the minimum I can pay to get my transaction included?
My worry is that usually the “Pay as little as I can get away with”, or “Pay a little bit more than the person that pays least.” tends the system to zero. The game theory of unlimited vacation days in corporations is a good example of this.
Perhaps system norms can fight this, or even displaying average gas-tip per block in the UX so users are encouraged to keep what is working working and can tip extra if they are impatient. This is probably something that will be seen as it runs on the network and the network can adapt to it through off chain coordination. Or, perhaps the cost of inclusion of a transaction is so low it won’t even be a problem.
Overall, I really like this idea of separating the auctions of gas-limit (network throughput) and block inclusion.
I see like this EIP is trying to exchange current “high volatility gas price scheme” + “transactions prioritized by explicit gas price” with “low volatility gas price scheme” + “transactions prioritized by implicit gas price”.
So you are trying to fix gas price volatility with formulas allowing this price to be changed slowly from block to block.
I see the following problems here:
- Implicit gas price will not allow working with exact balances, it will be hard for example to spend all ETH balance from the wallet
- Miners could decide if a transaction is even worth to be considered, this usually means using ETH price in calculations, which can not be handled by formulas.
The first point I don’t think will be much of a problem. The base_fee will be very predictable and if it works out as intended the miner_tip that miners will accept will also be stable. Or, at least the minimum tip they would consider.
The second point is something that we will see as it gets deployed. It is definetly possible that miners could reject transactions based on the tip being too low. It may also be that they get together as a group and “demand higher wages”. This would be a tough sale as rogue miners could swoop in to get increase profits, so there is likely an equilibrium there. Hard to tell where it will be until we get there. It is also depends on how coordinated the miners can be. And, by miners I really mean mining pools.
I wrote a post providing economic analysis about EIP-1559 in May. I had thought that maybe it is not necessary to publish it as others could provide similar thinking. But when I saw that someone still proposed it to Istanbul upgrade, it seems that many people still didn’t know its influence on the network.
EIP-1559 is just making tips become the gas fee, and making BASEFEE a tax on transaction. Finally, as BASEFEE will change according the using rate of gas limit in last block, it will serve as a policy similar to lock the maximum of size of block.
And all of all, it could not make user’s life eaier or make the actual fee predictable.