-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
docs: ADR-048 a multi-tier in-protocol gas price system #10653
Conversation
- No priority conflict with custom priority based on transaction types, since this proposal only occupy three priority levels. | ||
|
||
### Negative | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is perhaps the case for all dynamic fee systems, but one negative or neutral consequence will be that Tendermint's create-empty-blocks = false
option won't work, because the state / app hash will keep changing at every block
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When create-empty-blocks = false
, the validator doesn't propose new blocks when there's no tx, the consequence is the gas price is not adjusted in the meantime?
We already have ADR-47: #10602 (It was created earlier). |
Is there any more literature on this IOHK mechanism? The linked blog post is very light on detail. EIP-1559 is well modelled and studied in the wild. Even if this other mechanism has some desirable properties EIP-1559 seems like a good SDK default if only due to available information. Willing to be convinced otherwise so please share further info. Also, FYI, we want fees to be customisable and moved to a middleware design to make this more straightforward. |
There's no more detailed information other than the blog yet. |
e1995c0
to
2dc17f9
Compare
Thanks, renamed. |
|
||
##### Negative | ||
|
||
- Can't include urgent transactions with priority. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this would be built into the middleware imo. If a chain needs a special tx they would be aware of this and preprogram it
Reading through this, it makes me think if we could have real world numbers in cosmos that would allude to a decision. EIP-1559 while nice doesn't bring much value to chains that have little volume as the fee may end up at 0 anyways? Basic tx priority is currently merged into the sdk, past this, if a chain has multiple tokens as fees, they would have to implement some kind of oracle to get the price of this token compared to others. |
##### Negative | ||
|
||
- Unpredictable. | ||
- Overpricing the tip price in theory TODO I guess we don't obverse this in real world on ethereum ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if there is a sudden congestion owing to huge price volatility of assets, EIP-1559 will degrade to first price auction
Actually, this is one of the places where multi-tier design is better than EIP-1559:
The current implementation seems to fit in the "first price auction" category, right? |
kind of. since there's no prioritisation you're not auctioning anything really. will change soon. maybe @dogemos has an opinion on supporting a multi-tier fee model. |
I think the current master already prioritize tx based on the fee it pays: https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/middleware/priority.go#L38. |
### Positive | ||
|
||
- The default tier keeps the same predictable gas price experience for client. | ||
- No priority conflict with custom priority based on transaction types, since this proposal only occupy three priority levels. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- This multi-tier pricing system should be considered as only a default one for Cosmos-SDK.
- If the application wants customized priority based on transaction types, they could implement their own pricing mechanism by overriding the code or reusing the code, for example:
Giventype PrioritizedTx interface { Priority(ctx) int }
tier
is an optional field for transaction, the application could custom priorities for different transaction types without consideringtier
by implementing this interface for customized transaction type in application level.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to see some sort of fallback gas policy that applies to all transaction types. This could be a possible instantiation of the fall back policy.
Takes for instance Terra Oracle Msgs or or GravityEthereum messages.
For example, the Terra ante handler checks to see if all the msgs in the multimsg are oracle messages and applies one fee policy and otherwise applies the fallback fee policy. https://github.com/terra-money/core/blob/main/custom/auth/ante/spamming_prevention.go#L50-L104
We really want to enable use cases like Terra to operate without having to override the entire interface and instead provide middleware that composes with this system. If all the middleware before the multi tier fee module returns nil, then the multi tier fee model applies. In the terra example, if a multi msg combines both oracle msg and bank send messages than the multi tier fee model would apply to both. If the multi msg is all Oracle messages than the messages would have max priority or post ABCI++ use reserved oracle message block space.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Muggle-Du totally - we don't want to have a single choice.
@zmanian good point - this should definitely compose with other functionalities.
|
||
#### First price auction | ||
|
||
Before EIP-1559, ethereum miners select transactions ranked by the highest fees, which creates a first price auction market. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is what we are using now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ADR must have more clarity in the design:
- how are we going to update the transaction structure?
- I think we need a design which enables optional activation (so chains can update to newer SDK without being forced to use the new fee model).
|
||
Since tendermint 0.35 has supported mempool prioritization, we can take advantage of that to implement more sophisticated gas fee system. | ||
|
||
### Compare Different Designs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think ADR is the right place for making comparisons.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed now.
- The default tier keeps the same predictable gas price experience for client. | ||
- No priority conflict with custom priority based on transaction types, since this proposal only occupy three priority levels. | ||
|
||
### Negative |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is a negative consequence: the update will require wallets & tools update.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, it might need the TM core protocol upgrades support.
def txPriorityHandler_checkTx(ctx, tx): | ||
res, err := next_CheckTx(ctx, tx) | ||
# pass priority to tendermint | ||
res.Priority = Params.tiers[tx_tier(tx)].priority |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we still need to order transactions in a tire. Probably we still need to add gas price component here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the point in this design is to not order tx by price directly. Of course, we still have the issue if people all flooded to the higher tier, the lower tier won't have a chance to get included, the potential solution reserves block area for each tier, but that'll need to change tendermint.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We know that ordering only by price is not the perfect solution, but it's the most general one which is good for simapp example, until we have something better. We want transactions prioritized by type , price and and transaction distribution (by type).
That being said, an ADR proposal must be more complete.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of the tires can definitely be full, so we should decide about the order. It can be FIFO or or anything... I think ordering by gas price makes most of the sense in this design.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the order would be FIFO
under the same tier/priority.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, so let's add it to the doc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this ADR needs the TM core to change the tx behavior in mempool. Maybe needs TM core to support the plug-in mempool(separate the mempool component from TM core) for supporting the ADR requirement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tendermint 0.35 can already prioritize transactions, and we also have a primitive example in the SDK how to use it.
|
||
The original proposal reserve block segments for different tiers, we can't do that without modify tendermint, but it should be good enough to just specify higher priority for higher tier transactions. | ||
|
||
The lowest tier can use constant gas price, the higher tiers adjust gas price based on block load at different speed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If blocks are consistently full, then won't the lowest tier txs just never make it in, removing the "predictable pricing"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once we have ABCI++, we reserve a portion of block space for medium and low fee tiers to ensure that this pool of transaction is slowly drained even in full block space environment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't that just create an out-of-band tx fee market then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't that just create an out-of-band tx fee market then?
within the same tier, the txs are processed in FIFO manner, avoiding the competition on gas price.
I'm still thinking we should stick to EIP-1559 as the sdk default. We want to make it easy for people to augment and experiment with alternatives, but simplicity and a well understood mechanism is pretty important as a baseline. I'd like to push to get typed transactions that can reserve block space, but I'm still of the opinion that this should be future work. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- decide if we want to do comparison in the ADR
- improve design to allow priority composability
- update consequences
consensus_price = State.gas_prices[tx_tier(tx)] | ||
min_price = max(validator_price, consensus_price) | ||
|
||
if tx.gas_price() < min_price: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how the user will know what gas price to use? Maybe if we use 0
then we should automatically adjust and set the min_price
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to keep exiting tx fields and semantics in this proposal, but maybe it makes more sense to change it to gasPriceCap
, so it'll always be charged with what's computed on-chain as long as the computed price <= gasPriceCap
. And we shouldn't use the per-validator minimal-gas-price
anymore, it's not compatible with the consensus logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated proposal to change gasPrice
to gasPriceCap
, the actual gas price used is the one computed in consensus.
### Positive | ||
|
||
- The default tier keeps the same predictable gas price experience for client. | ||
- No priority conflict with custom priority based on transaction types, since this proposal only occupy three priority levels. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Muggle-Du totally - we don't want to have a single choice.
@zmanian good point - this should definitely compose with other functionalities.
f6b4384
to
f0fce5a
Compare
- Tier 2: a dynamic gas price which is adjusted according to previous block load. | ||
- Tier 3: a dynamic gas price which is adjusted according to previous block load. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are identical BTW
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added: "at a higher speed".
|
||
Add a new `tier` field in `Tx` to specify the preferred tier of service. | ||
|
||
Change the semantic of `gasPrice` to `gasPriceCap`, which is the maximum gas price can be charged, if the consensus gas price is larger than `gasPriceCap`, the transaction should be rejected. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the consensus gas price acts as a floor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the consensus gas price is the actual gas price user is charged, since it's dynamic, the gasPriceCap
is to prevent that price is unexpectedly high to user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we rephrase:
"the transaction should be rejected" -> "the transaction won't be included and will stay in the mempool until the gas will go to the gasPriceCap
level. The mempool can eventually prune old transactions"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, that's better, changed.
implementation-wise, that'll need abci++ right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so, the mempool management is already there. Let's double check with @cmwaters
45ebb87
to
fae48fe
Compare
ce29ba7
to
e2024d3
Compare
done |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost there:
- This snippet should be updated: https://github.com/cosmos/cosmos-sdk/pull/10653/files#r788646099
- Expand information about FIFO
- that this is the default mechanism, delivered by Tendermint
- FIFO within a tire is not ensured by consensus so a validator can tweak the Tendermint code to order txs in a tire differently
- add a note about composability:
- we should be able to create tires by Tx type: this way we can easily prioritize both by user tire selection and tx type (eg to prioritize evidence or IBC transactions)
def txPriorityHandler_checkTx(ctx, tx): | ||
res, err := next_CheckTx(ctx, tx) | ||
# pass priority to tendermint | ||
res.Priority = Params.tiers[tx_tier(tx)].priority |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tx_tier
returns number, so we should remove .priority
.
res.Priority = Params.tiers[tx_tier(tx)].priority | |
res.Priority = Params.tiers[tx_tier(tx)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, the original one is good I think, tx_tier(tx)
returns the gas_tier
, which is used to index the tier parameter list Params.tiers
to get the tier parameters, then use the configured .priority
field of it as the tx priority.
I'm not sure about this part, we can use different priorities based on tx types, but that takes completely different tx type, not just msg types. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's make the final round and get approvals. cc: @aaronc , @hxrts , @zmanian , @alexanderbez
I've added a commit explaining tx priority composability: c85d663 |
LGTM |
good catch, fixed. |
Hey, on one of the previous architecture calls we talked about the maintain of this feature and how it would be done on top of the feature's inclusion in the sdk. At the end there was a larger portion of people agreeing that we can merge the Protobuf changes to allow applications to use this but we shouldn't merge this into the sdk itself. It is unclear who all wants this structure and I would opt for users writing their own or using this feature which would be hosted in a different repo. |
I think it's still good to have this ADR and merge it. |
merging this is a requirement, but should mark as rejected for being housed in the sdk or something along those lines. |
Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>
Any reason this was merged as rejected instead of proposed? |
#10653 (comment) |
the mechanism requires some tx proto customization, which we added. |
Description
Discussion thread about in-protocol gas price: #8224
Author Checklist
All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.
I have...
!
to the type prefix if API or client breaking changeCHANGELOG.md
Reviewers Checklist
All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.
I have...
!
in the type prefix if API or client breaking change