simd | title | authors | category | type | status | created | feature | supersedes | extends | |
---|---|---|---|---|---|---|---|---|---|---|
0110 | Exponential fee for write lock accounts |
| Standard | Core | Draft | 2024-01-18 | (fill in with feature tracking issues once accepted) | (optional - fill this in if the SIMD supersedes a previous SIMD) | (optional - fill this in if the SIMD extends the design of a previous SIMD) |
Summary
In a permissionless environment with low fees, users often submit transactions for opportunistic trades without considering the success probability. Almost half of the Compute Units (CUs) in a block are allocated to failed transactions, leading to undesirable scenario where large portion of compute powers primarily serving failed DeFi arbitrage transactions. To address this, the proposed feature introduces economic back pressure, discouraging spam activities and ensuring efficient network resource utilization. It suggests tracking the Exponential Moving Average (EMA) of contentious accounts' CU utilization per block and exponentially increasing the cost to write-lock these accounts if their utilization remains high.
Motivation
The motivation behind this feature is to introduce economic back pressure, dissuading DeFi spammers from overwhelming the network. DeFi spam, defined as opportunistic trades with a positive return on investment, currently occupies almost half of the CUs in a block as failed transactions. Economic back pressure aims to create a deterrent for such spam activities, ensuring network resources are efficiently utilized and preventing continuous block congestion caused by failed DeFi spam transactions.
Alternatives Considered
While the priority fee serves to mitigate low-cost spams by decreasing the likelihood of less prioritized transactions being included, it cannot entirely eliminate the inclusion of spam transactions in a block. As long as there remains a chance, no matter how small, to inexpensively include transactions, the incentive for spamming persists. The proposed feature recognizes that the current mechanisms have limitations in fully addressing the spam issue, and thus, seeks to introduce a more robust solution to discourage opportunistic trades and ensure a more secure and efficient network environment.
New Terminology
-
compute-unit utilization: denominated in
cu
, it represents total compute-units applied to a given resource. -
cost rate: denominated in
lamport/cu
, it represents the cost per compute-unit at a given condition. - compute unit pricer: a component tracks Exponential Moving Average of compute-unit utilization, applies a pricing algorithm to provide current cost rate.
-
write lock fee: denominated in
lamport
, it is fee dedicated for write lock an account, calculated ascompute-unit-pricer.cost-rate() * transaction.requested_cu()
.
Detailed Design
Design Highlights
- Account Association with Compute Unit Pricer:
- Accounts are associated with a compute unit pricer, and the runtime maintains an LRU cache of actively contentious accounts' public keys and their compute unit pricers.
- Alternatively, each account can have its compute unit pricer stored onchain, which would require modifying accounts.
- Compute Unit Pricer:
- Tracks an account's EMA compute-unit utilization, updated after the current bank is frozen.
- Provides the current cost rate when queried.
- EMA of Compute-Unit Utilization:
- Uses 8 slots for EMA calculation.
- EMA Alpha, representing the degree of weighting decrease, is calculated as
alpha = 2 / (N+1)
.
- Pricing Algorithm:
- Adjusts write-lock cost rate based on an account's EMA compute-unit utilization.
- For each block, if an account's EMA compute-unit utilization is more than target utilization, its write-lock cost rate increases by X%. If it's below target, the cost rate decreases by X%.
- For V0:
- target utilization is
25%
of Max limit; - Initial write-lock cost rate is
1000 micro-lamport/CU
; - cost change rate set to 1%;
- target utilization is
- Calculate Write Lock Fee:
- Fee required to write-lock an account is calculated by multiplying the write-lock cost rate by the transaction's requested CU.
Detailed Design
- Initialization and Inheritance:
- Bank initializes an empty account_write_lock_fee_cache, an Cache of {account_pubkey, compute-unit-pricer}.
- Child banks inherit the parent's cache.
- Transaction Fee Calculation:
- Calculate write-lock fee for each account a transaction needs to write, summing up to be its write lock fee. This, along with signature fee and priority fee, constitutes the total fee for the transaction.
- Leader checks fee payer's balance before scheduling the transaction.
- Cost Tracking:
- Cost_tracker tracks CUs for the current block and each write-locked account as-is;
- Ensuring cost tracking is enabled at the replay stage.
- End of Block Processing:
- Identify write-locked accounts with compute-unit utilization > target utilization. Add/update bank's account_write_lock_fee_cache.
- For those accounts are in cache, eg were saturated, but not being write-locked in this block, their current block compute-unit utilization shall be considered as zero; then use it to update Cache.
- Evict cheapest account before add new "hot" accounts into LRU cach, if cache is in full capacity;
- Account will be evicted from cache as soon as its cost rate drop back to 0
- Cache has capacity set to 2* worst case eviction per block to prevent cache attack.
- For v0, cache capacity set to 2048, as:
- Max number of tansactions with account 6M CU = 48M/6M = 8;
- Max number of accounts per tx: 128;
- worst case per block: 128 * 8 = 1024;
- 2 times worst case: 2048;
- Fee Handling:
- Collected write-lock fees are 100% burnt.
- Collected priority fees are 100% rewarded.
- Collected signature fees are 50% burnt, 50% rewarded.
Other Considerations
- Users may need new instruction to set a maximum write-lock fee for transaction
- Consider tooling for wallets/simulators to query "min/max write lock fee."
- Acknowledge read lock contention, deferring EMA fee implementation for read locks.
- In the future, a percentage of collected write-lock-fee could be deposited to an account, allowing dApps to refund cranks and other service providers. This decision should be done via a governance vote.
Impact
- Rate of successful CU inclusion in a block is expected to increase, reducing failed transactions.
- Transactions writing to contentious accounts will experience increased fees, particularly during congestion.
- DeFi arbitrage traders will need to adjust strategies to account for the heightened fees.
Security Considerations
none
Backwards Compatibility
Needs feature gate.
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 a pretty big assumption. I'd like to see the tx scheduler improvements land in 1.18 before this gets seriously considered. Given how the tx scheduler is currently implemented, it's hard to say priority fees aren't sufficient to adjudicate access to blockspace.
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.
Am confident improved scheduler in 1.18 will respect priority fee much better, but there is still chance, hight be very small, that lower prio tx lands before higher one.
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 the probability of low-prio txs getting included is low. Then it seems like the EMA raising fees will mainly affect the non-spam devs/users who will now see raised fees. If non-spam is anywhere close to 6M CUs/block, then non-spam users pay and low-priority spammers will only get hit by high fees very rarely?
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.
user will pay more when capacity is reduced; once this is reliably predictive, spammer will have to back off; and normal users pay resources per demand.
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.
@crispheaney steady state ingress load on leaders is 50kpps+. The pipeline to dedup/sigverify/fee check, has to handle all that load before it gets to the scheduler. If it takes more then 400ms, tx isn't getting prioritized in that block. The only way to get spammers to send fewer txs is to raise the base layer fee.
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 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 if txs take too long to get through the pipeline, prioritization is not effective. Does that make sense? Doesn't matter what the scheduler does, if it can't see txs because they are still in the queues. we need to force sender to stop economically
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.
It seems reasonable we focus on improving the throughput scheduling and pre-scheduling stages so that it's more likely txs are able to be prioritized.
If the chance of inclusion for spam is low, then I'm not convinced they will back off.
Fee-payer is can be totally separate from the account funding economic activity for arbitrage.
I can keep my fee-payer balance low and continue to spam. If the fees get too high for my account to fund, then oh well my tx won't make it into the block because the leader won't include me since I can't pay fees.