Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

Consider adding user specified fees to prioritize txs propagation to the leader/block #22820

Closed
aeyakovenko opened this issue Jan 28, 2022 · 24 comments
Labels
stale [bot only] Added to stale content; results in auto-close after a week.

Comments

@aeyakovenko
Copy link
Member

aeyakovenko commented Jan 28, 2022

Problem

No way for users to easily prioritize transactions landing in a block outside of staking directly or indirectly.

Proposed Solution

V0

Ship this asap. Even with deterministic congestion control, an additional user specified priority is necessary. If there is a bug in the validator client and performance stalls, logically the blocks are not saturated and deterministic fees may not trigger. Clients need some way to force their txs to the front of the queue.

  1. ComputeBudget instruction in Add fees to tx-wide caps #22081 should take a fee argument
  2. txs should be pulled from connected nodes with QoS by stake weight in Add quic port for accepting transactions #22753
  3. Cost model should fill writeable accounts using total fee/total tx cost as the priority. Hot accounts will saturate first with highest paying txs, but will not impact the fees for other accounts.
  4. Node should forward remaining forwardable txs based on the priority. The forwarders would need to run the same computation as in step 2, filling one account at a time, otherwise the high priority txs that all saturate one account will starve the other accounts. Once account is filled, txs that write to that account have zero value since they can't land into the block.

Add an RPC api that given a transaction, checks for lowest possible fees paid by txs in the last 32 blocks and if they are saturated, and lowest possible fee paid for the writable accounts referenced in the tx if those accounts are saturated. the highest of the two should be what the tx should pay to get prioritization. In the design, a fee spike should be write account specific. a hot market that seeing a lot of bots, that specific account will see a fee increase, but all the other ones shouldn't. This is because once the write limit is hit for the account we can't add any more txs to the block for that write to that account.

V1

There is enough MEV on the network that a validator would take a bribe that is greater than the 50% of the additional_fee to include a transaction instead, on solana 50% of the fee is burned. Eth EIP 1559 splits fees into a congestion base fee that is burned with a tip that 100% goes to the validator. The challenge for solana is that write lock accounts are saturated independently of blocks, and need their own congestion control.

  1. Add a multiplier for unnecessary write accounts, Consider increasing fees for writable accounts #21883

  2. Congestion fee based on the load that doubles when accounts are saturated, and when blocks are saturated. This is tricky because an account could be saturated in block 1, and block 5, if block 2,3,4 are forked, or saturated, fees should double as well.

  3. make the tip 100% go to leader, burn the congestion fee

tag @jackcmay @jstarry @taozhu-chicago @sakridge

@buffalu
Copy link
Contributor

buffalu commented Jan 28, 2022

these are my not-very-well formed stream of consciousness thoughts haha

my main concern would be this stuff breaking down when more people start to run custom validators to maximize profits. you're specifying you're willing to pay extra to get processed faster, and as a validator i'd be very happy to accept this extra money! however, the only thing better than receiving 50% of this payment would be 100% of it.

  • do you want priority fees to go 100% to validator or do you want it to leverage the 50% validator/50% burn used right now?
  • along with the above question, if im a validator running custom MEV software and can choose between using the default logic you've proposed versus a side channel payment system where i earn 100% of the fee, why would i chose to burn 50% if i can get 100%?
  • for instance, we have a contract that handles the eth.coinbase equivalent for solana and allows the validator to claim this at the end of their slots/scheduled time. why would a validator choose the method you suggested as opposed to looking at the transfer amount to these token accounts and capturing 100% of the fee?

it seems fine for normal users willing to pay for fast tx processing if/when blockspace becomes saturated, but as we've seen on ETH it seems hard to enforce this type of ordering forever with automated bots and could even result in PGA-type scenarios. maybe the workaround for this stuff is some type of base fee handled on per-account basis and enforced by the protocol; if you pay less than base fee you've produced an invalid block

@buffalu
Copy link
Contributor

buffalu commented Jan 28, 2022

it just seems inevitable that out-of-band payments will happen (and are already are happening from what im hearing 😢 ), so trying to enforce anything except direct-to-validator or direct-to-staker payment seems like a hard sell

@aeyakovenko
Copy link
Member Author

aeyakovenko commented Jan 28, 2022

@buffalu I think incentives can be adjusted later. Eths burn is quite significant and hasn’t caused a massive direct to validator bribe side channel (although there is def some).

the other approach is to double the fees every time an account is saturated or every time a block is saturated. eip1559 is pretty decent way to split the problem, congestion base fee + validator tip. The hard part in solana is the account model. account hotspot congestion occurs first and generally without block congestion.

@buffalu
Copy link
Contributor

buffalu commented Jan 28, 2022

the other approach is to double the fees every time an account is saturated or every time a block is saturated. eip1559 is pretty decent way to split the problem, congestion base fee + validator tip. The hard part in solana is the account model. account hotspot congestion occurs first and generally without block congestion.

yeah something like this seems reasonable. there's a base cost for access to certain resources that everyone has to pay no matter what. if you want priority access/ordering you can pay extra and have the validator handle it.

@bji
Copy link
Contributor

bji commented Jan 29, 2022

Why 100% of tip goes to leader? Why not burn 50%? Then buying priority at least benefits everyone in the network as well as the validator who gets the tip.

@buffalu
Copy link
Contributor

buffalu commented Jan 29, 2022

Why 100% of tip goes to leader? Why not burn 50%? Then buying priority at least benefits everyone in the network as well as the validator who gets the tip.

how do you enforce that? if im running a validator, why would i give 50% away?

@bji
Copy link
Contributor

bji commented Jan 29, 2022

I assumed it was to be built into transactions somehow and validated by other validators before being voted on. Otherwise, it's not part of any proposal anyway as it's something completely out of band with the validator software.

Having a standardized field where a user can declare a tip that will go to whatever validator includes it in a block allows the transaction to carry the tip with it, which means that it survives being forwarded, etc.

EDIT: I assume that "tip" is the same thing as the "additional_fee" field that was proposed to be added to the transaction. Is that not so?

@buffalu
Copy link
Contributor

buffalu commented Jan 29, 2022

imo it makes sense for additional_fee to be an extra instruction or CPI?

wallets will probably use a tx instruction with static amount, bots will use CPI with runtime-determined amount (can simulate to determine ordering)

@aeyakovenko
Copy link
Member Author

imo it makes sense for additional_fee to be an extra instruction or CPI?

wallets will probably use a tx instruction with static amount, bots will use CPI with runtime-determined amount (can simulate to determine ordering)

Might as well reuse the ComputeBudget methods. Most txs will likely want to specify something there.

@buffalu
Copy link
Contributor

buffalu commented Jan 29, 2022

Might as well reuse the ComputeBudget methods. Most txs will likely want to specify something there.

would 50% get burned or would 100% go to validator? i think anything that relies on ordering where some % will be out-of-banned, so it seems like best way is to just do it out-of-band from the get-go.

also can you CPI compute budget increase?

@tomland123
Copy link

tomland123 commented Jan 29, 2022

Really love this!!! I think Buffalu is a little bit wrong on capturing 100% vs 50% of the fees. AFAIK are going to be severe costs to running your own MEV code, like needing a $2k/month machine cost on top of your normal validator. This really constrains smaller staked validators who wont be able to economically afford the increased hardware costs -- so there will always be players using the base 50% fee model even in the most naive cases.

However, I am wondering if there could be a way for validators to get angry/slash if high fee validations are getting reordered away from them because someone is dequeuing these txn and acting rogue for their own benefit.

If you could have a way for validators to police other validators into accepting this fee structure and take a lot of risk reordering, this would solve almost every problem I could associate with MEV.

I feel (but dont know) if there were multiple leader nodes you could do something to police out this reordering thing in most cases.

@buffalu
Copy link
Contributor

buffalu commented Jan 29, 2022

the fee structure doesn't have anything to do with whether a validator runs MEV or not, it just comes down to the validator maximizing their profits.

the out of band payments with 0% burn are inevitable, its pretty trivial to handle on-chain, so assuming that's the case, as a user you should want the out-of-band payment that burns 0% because if you choose to use the system that burns 50% of the fees, you'll have to pay 2x as much to be worth it to the validator that uses the direct-payment method.

very skeptical of validators getting slashed for reordering, too much money on the table and hard/impossible to prove.

@tomland123
Copy link

tomland123 commented Jan 29, 2022

Why do votes burn 50% of the txn fee? I am assuming this would be built into the chain and validators who dont follow it will be ignored/slashed in the future?

I agree that its very difficult for validators to be slashed for reordering right now but if during consensus there are parallel leader nodes and 3 leader nodes are saying one thing and the 4th is clearly reordering because the highest fee txn isnt appearing where its supposed to be, there could maybe be a software solution to say "hi this is clearly wrong and we should ignore this persons opinion for this blockhash"

maybe i am super wishful thinking. I hate MEV so much and the lack of it is one of the reasons I fell in love with Solana

@buffalu
Copy link
Contributor

buffalu commented Jan 29, 2022

Why do votes burn 50% of the txn fee? I am assuming this would be built into the chain and validators who dont follow it will be ignored/slashed in the future?

same way that normal transaction fees are. there's an enforceable cost for the resources used (signature verification) and every validator agrees what resources were used + the price by checking transactions + they subtract from accounts automatically. if you produce a block that doesn't subtract those fees or doesn't follow the rules, the block is deemed invalid by the network.

we'll see what happens with multi-node leader schedule, not quite sure how that'll work out haha

maybe i am super wishful thinking. I hate MEV so much and the lack of it is one of the reasons I fell in love with Solana

solana has mev, its the main reason the chain struggles during market volatility. we're doing what we can to make it better.

@tomland123
Copy link

tomland123 commented Jan 29, 2022

hello, MEV that is akin to gambling through spam is completely different than reordering txn to do w/e the hell you want. You are limited in the amount of user hating stuff with the brute force method. You can do a lot of life ruining things with reordering and I dont think DApp developers will even know what is happening to them until its too late.

But yes, I understand your point!

In regards to the enforceable costs: Couldnt there be like a hashmap of static priority fees so you just pass in the the resource and that determines the burn/tip rate then? That way everyone who uses the same hashmap sees the same burn fee and txn fee to be in a higher priority. I dont know if these fees need to be super dynamic.

@aeyakovenko
Copy link
Member Author

aeyakovenko commented Jan 29, 2022

In regards to the enforceable costs

There are costs associated with each account read/write, instruction, BPF cycle, cpi, etc. all those are rolled up as a "compute unit". Ideally the network should run at something like 80% capacity without saturating any single writable account. Once accounts are saturated, the network should automatically increase the base fee for using that resource. The reason for this is because a single writable account that is constantly saturated creates a single thread dependency across processing the chain, it makes it slow for nodes to catch up and leverage multi core environments. Adding automatic congestion control is part of V1.

Why do we need a direct to validator tip/additional fee at all? Let's say there is a bug that causes something in the validator pipeline to stall, and take a bit more time to process. Number of txs that land in the block drops, so blocks are not logically saturated, but they are saturated in real life. we still need some way for clients to always be able to prioritize txs ahead of every one else.

@CherryWorm
Copy link
Contributor

CherryWorm commented Jan 29, 2022

Why would I as a validator not just deploy a patch (that is probably going to be very small and easy to maintain) that orders by fee/cu budget globally, instead of locally for each writeable account? I don't think this would be a bad thing, but I know you don't want a mempool, and this proposal is exactly how you're going to get a mempool imo

@aeyakovenko
Copy link
Member Author

aeyakovenko commented Jan 29, 2022

Why would I as a validator not just deploy a patch (that is probably going to be very small and easy to maintain) that orders by fee/cu budget globally, instead of locally for each writeable account?

you wouldn't earn as much though, right? once the writable account is saturated the value from the additional txs for that account is zero.

When the leader is pulling new txs from the staked nodes we don't want TXs that saturate a single account to be the only thing it pulls, otherwise the blocks are not going to be full. it will just be that one account and the system would end up in single threaded mode.

@t-nelson
Copy link
Contributor

also can you CPI compute budget increase?

No. Compute Budget instructions are handled by the runtime, so need to be visible pre-execution

@j-h-a
Copy link

j-h-a commented Jan 31, 2022

Here is what I'd like to see:

  1. Fixed fee-per-signature [1].
  2. Increasing fee-per-100k-compute-unit [2].
  3. Network congestion multiplier [3].
  4. Priority multiplier [4].

[1] As we have now.

[2] First 200k CU is included, then an increasing fee per additional 100k CU, for example 5k lamports for the first additional 100k CU, 10k lamports for the next 100k CU, 15k lamports for the next 100k CU, etc. Must be declared up front, reflects TOTAL CU, not per-instruction/invocation or whatever; All fees still charged if stated CU is exceeded.

[3] All fees from 2 can be multiplied by a factor based on network load (always >= 1.0) - this can change PER SLOT but needs to be some slots in advance such that a fees calculation will be valid for 20s or so, allowing humans looking at a UI to confirm and know it will work. It would be nice if simple tx < 200kCU remained at a fixed price, so 1 not included in this multiplier, but could be included.

[4] Users can choose to apply any integer multiplication factor they like (>= 1) to the fees, for priority. Validators will guarantee that at least 1 normal (no priority_factor, or priority_factor = 1) transaction is processed for each priority transaction within a slot.

I also think validators should get to keep more fees relative to their processing (linear) but that the additional fees (like the exponential component of the CU prices and the priority fees) should be burned.

@aeyakovenko
Copy link
Member Author

@j-h-a how is 4 different from the additional fee parameter? Validators can't guarantee that a high priority tx is seen when they make a block, so that guarantee is impossible.

@j-h-a
Copy link

j-h-a commented Jan 31, 2022

The guarantee is only that they include an equal or greater number of "normal" (i.e. no priority fee paid) transactions, to approximate a twin-queue system, where tx are taken from both queues (It's not really a queue, but would behave similarly). The intention is to prevent priority fees from spiralling upwards, pricing out regular transactions. A proposed block that doesn't meet this should be voted against. I don't understand the account-write saturation, or how fees for that would work. My intention was only to propose an incentive that steers the network back to not needing priority fees at all - i.e. if too many people were paying for priority, and that "queue" was bigger than the unprioritised one, then you'd actually be better off NOT paying priority fees.

@aeyakovenko
Copy link
Member Author

@j-h-a yea, I this is a hard problem, because the txs are paying not just for blockspace, but for prioritization across all the queues. so while the block may reflect X messages of priority 2, the queue leading up to it could have been filled with a tons of messages of priority 1. so its hard to prove it to the chain that's what happen.

one thing that could work is having the lowest paying fee be the one that is charged to everyone per one writable account. we can experiment with those things in v2 or v3

@wkshare
Copy link

wkshare commented Feb 10, 2022

@aeyakovenko
Is TPS 3000 already saturated? Why not find a way to continue to increase TPS?

@github-actions github-actions bot added the stale [bot only] Added to stale content; results in auto-close after a week. label Feb 10, 2023
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Feb 20, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
stale [bot only] Added to stale content; results in auto-close after a week.
Projects
None yet
Development

No branches or pull requests

8 participants