Skip to content
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

Block budget usage in Nakamoto #5398

Closed
obycode opened this issue Oct 29, 2024 · 67 comments
Closed

Block budget usage in Nakamoto #5398

obycode opened this issue Oct 29, 2024 · 67 comments

Comments

@obycode
Copy link
Contributor

obycode commented Oct 29, 2024

With Nakamoto activation, a Stacks miner can quickly use up nearly its entire budget for the tenure within the first few blocks. After that, it will only be able to include an occasional cheap contract call or primarily STX transfers in new blocks for the rest of the tenure. This behavior is not a surprise, but it is an area where we could potentially do something better. This issue will be for brainstorming options to improve this problem.

@obycode
Copy link
Contributor Author

obycode commented Oct 29, 2024

Issue #5397 aims to help with this problem by improving mempool walking.

@github-project-automation github-project-automation bot moved this to Status: 🆕 New in Stacks Core Eng Oct 29, 2024
@obycode
Copy link
Contributor Author

obycode commented Oct 29, 2024

The obvious thing to do is to make the signers enforce a pacing of the budget usage, such that the miner would need to spread the costs over a 10 minute period. The problem with this is that if the miner is pacing the cost out for 10 minutes but the next bitcoin block arrives in 2 minutes, then the tenure was not utilized to its full potential. This would also make expensive transactions less likely to ever be included in a block, since they make take up more than the segmented cost.

@obycode
Copy link
Contributor Author

obycode commented Oct 29, 2024

Updating the cost limits could help with this problem somewhat, giving the miner more space to fill. The fact that miners can fill a block and get it signed so quickly indicates that the current cost limits are likely too low.

@obycode
Copy link
Contributor Author

obycode commented Oct 29, 2024

Another option is to make a change in the mining heuristics only, so that it will pace out the block budget on its own, without any restrictions from the signer. This would avoid any potential conflicts and strange incentives that could come from the signers deciding how to pace. The miner is incentivized to reserve block space throughout its tenure so that it has room for potential high-paying txs that show up later in the tenure.

@JakeBlockchain
Copy link

Been thinking about this a little as fee estimation is a big UX boost if done right. With all of Bitcoins slow block issues, accurate fee estimates with the mempool make it decent enough to use because you know what to expect.

At first glance, letting the miner frontload their blocks with the highest fee TXs is rational, to limit a fast Bitcoin block leaving money on the table.
But as Stacks mining is a probabilistic game that rewards long-term players. This downside shouldn't affect miners that much.

Forcing pieces of the blockspace to be filled over a set period of time seems like the best way to balance user UX while also allowing "in-tenure" fee markets to arise.
Maybe spread the blockspace over 5 minutes as a happy medium to account for faster Bitcoin blocks. After that, the simple token transfer behavior will be limited to a few minutes on average.

@Rapha-btc
Copy link

Been thinking about blockspace constraints in Stacks. Spreading TXs across the 10-min tenure seems like a workaround, but what's actually preventing continuous processing, especially for DeFi?

Is there something fundamental about these limitations beyond the Bitcoin anchor? Or are we working with inherited design choices that could be revisited?

Curious what's really at stake here.

@vini-btc
Copy link

vini-btc commented Oct 29, 2024

I quickly analyzed block space usage from Stacks Block 169289 until 174376. Data and data gathering methods should be available here in this repo. I created some data visualizations for the key metrics in this observable notebook.

The key insight is that read_count is the biggest block space usage bottleneck. I believe the core team knows this well, so there are no big surprises. Here is the graph for read counts per tenure:

untitled

It looks like post-Nakamoto tenures are consistently maxing read counts, which is good since it signals v3 is efficient.

Spreading the space budget throughout the tenure wouldn't solve many issues, IMO.

Digging into the topic, I found @jcnelson already explored read optimizations: #3777 (comment). So, I believe there's a clear path to increasing read_counts (142 times, if I understood it right?!), which should significantly increase the number of transactions processed without any big compromises. That would be a consensus-breaking change, though. It's a bit of a shame it wasn't included in SIP-021, but anyway, at least there's even a (hopefully still relevant) POC done.

@siriusbtc
Copy link

siriusbtc commented Oct 30, 2024

Bitcoin block production time is uneven, not constant speed 10 min, sometimes 1 hours a block, sometimes 1 second a block, but the total tenture blocks size of Stacks is limited to 2mb, to get the max txs fees , miner who wins this tenture trends to fill full the first several blocks with txs to avoid rapid bitcoin block. That is the way how congestion happened.

So the simplest strategy to solve this issue is to increase the total tenure blocks size limit into a big size such as 1GB and set small size limit (200-500k) to Stacks micro fast blocks. This could address throughout issue and uneven Stacks block size issue at the same time.

@eriqferrari
Copy link

Increasing the blocks size seems the fastest solution, but based on @vini-btc analysis seems the read counts generate the bottleneck.. what about of grouping read/write counts to a cumulative 30k, instead of having 2 counters of 15k. it could generate about a 33% more of available space, optimizing the usage of each block.

like @Rapha-btc i would like to know if there are some limits on the tenure block that doesn't allows for bigger blocks.

@hugocaillard
Copy link
Collaborator

hugocaillard commented Oct 30, 2024

Edit: I just re-read some comments above and saw that @obycode suggested it in just a few lines.
But I guess my question is; could it be the default strategy for miners? And they could set how aggressive they want to follow strategy (keeping more or less space at the beginning of tenure, and how quickly it decreases)


Would it make sense for miners to always keep budget space for upcoming higher fees txs?
In short: the miner should always keep room to mine a potential high fees tx.

  • during the 1st minute of a tenure the miner could keep 90% of the block space for future high budget txs
  • during the 2nd minute, the miner could keep 70%
  • ...
  • during the 8th minute, miner would only keep 5%

The % to preserve could follow a inversed logarithmic curve, that could be more or less agressive depending on the miner settings.

It encourages users to pay higher fees if they want fast txs, while lower fees txs would take less priority and can fill remaining block space toward the end of tenure.

Please appreciate this graph that illustrates the idea:

Screenshot 2024-10-30 at 23 17 38

@augustbleeds
Copy link

augustbleeds commented Oct 31, 2024

hi guys. just giving my 2 cents ~ tbh I have no idea how stacks core code works so I'm just speaking from a strategic high-level. I think industry shows us that there's really only a few proven ways to increase tx throughput (TPS):

  1. increase block size
  2. stacking performance optimizations (parallelization, networking, etc.)
  3. rollups

3 is obviously out of the question. 2 is a long road of improvements. 1 is easiest to do in the short-term, but sacrifices decentralization in the long-term.

2 is the way forward ... probably first by cutting fat and then building muscle (if you get what i mean). But unless there are egregious issues, cutting fat would probably only lead to marginal improvements which may or may not be enough to get the network to be quick enough given the demand for block space. You'd probably need some hefty redesigns to see vast performance gains.

1 would be a short-term fix to get to an acceptable TPS.

godspeed! rooting for you guys.

@eriqferrari
Copy link

Hi @hugocaillard , this is a nice solution but doesn't solve the problem. Degens out there wants fast txs during all the tenure. If we remain capped to a max block size that allows about 5-600 txs per block will be difficult to onboard more ppl. We need Ethereum speed with Solana costs. That's what the community wants. I will personally increase slowly the block size, testing the response from the network. In the best scenario with 10 minutes Bitcoin blocks we can have 50-60 txs/min. Here is the real bottleneck. To succeed we need at least to go 100x, actually 5x or 10x will be enough to handle the market needs, but we are not prepared for the bull run. This is my investor sentiment, as a developer understand the difficulties to achieve it, but we need to risk a bit more.

If increasing block size is the short term solution, let's do it. If it requires a new SIP to be approved we need to hurry.

I still congratulate with all the core devs for the hard fork, but the fine-tuning is now crucial to success, and should be asap.

Eriq

@hugocaillard
Copy link
Collaborator

hugocaillard commented Oct 31, 2024

@eriqferrari
In my comment I only discuss one idea that could improve the situation. I'm also greatly in favor of other solutions, especially that ones that can increase the number of transactions included in a tenure. Increasing read count budget limit is definitely something I'd like to see as soon as possible 💯

Degens out there want fast txs during all the tenure

This is exactly what the solution I developed tries to address. Even with high budget limits and performances optimizations, there will be periods with high volume of txs and pressure on the network. With the current mining behavior, this would lead into tenure budgets being filled early in the tenure. By reserving block space for potential higher fees txs, it guarantes that fast txs can be mined during the whole tenure. And it also gives more meaning to the fees strategy. Of course, the fees doesn't need to be super high, just higher than the market.

@eriqferrari
Copy link

Great! Love to hear that @hugocaillard !!
your solution works very good, allowing more txs to be added during all the tenure. I didn't want to criticize that, but would like to focus on the real bottleneck that we are facing while submitting txs: the block size.
simple example: 100 = 50 + 30 + 20 = 80 + 15 +5 To achieve more transactions, we don’t need to change the order or size of the addends; instead, we need to work on increasing the total result. just try to imagine stacks with 10x the current daily users.
I really appreciate all of your works! it was nice to meet you in Adam too!!
We are all eager to be ready for the bull run, that's all! and we need to push the narrative now!!

@siriusbtc
Copy link

siriusbtc commented Oct 31, 2024

@hugocaillard in practice, there are more bitcoin blocks times exceeded 10 mins than we imagine, almost each day we could see at least one btc block exceeded 40 min, so the inversed logarithmic curve limit will not bring users fast experience too in many cases, after 8 mints, users will feel congested unavoidably too.

To have users get stable and continuous fast experience, set size limits on fast stacks block st the same time when increasing tenure block size is the simplest and effective strategies.

@hugocaillard
Copy link
Collaborator

hugocaillard commented Oct 31, 2024

@siriusbtc

there are more bitcoin blocks times exceeded 10 mins than we imagine

There's the tenure-extend strategy for that, where the miner gets a fresh new budget to keep mining.

set size limits on fast stacks block [instead of on the tenure]

It don't think this is something with want, this would greatly affect the whole mining logic and dynamic. Tenure budget exists for reasons. I don't think my current understanding of the matter would allow to clearly and effectively describe it so it'd be better to find documentation for that, or refer to someone with a deeper knowledge on the matter

@siriusbtc
Copy link

siriusbtc commented Oct 31, 2024

@siriusbtc

there are more bitcoin blocks times exceeded 10 mins than we imagine

There's the tenure-extend strategy for that, where the miner gets a fresh new budget to keep mining.

set size limits on fast stacks block [instead of on the tenure]

It don't think this is something with want, this would greatly affect the whole mining logic and dynamic. Tenure budget exists for reasons. I don't think my current understanding of the matter would allow to clearly and effectively describe it so it'd be better to find documentation for that, or refer to someone with a deeper knowledge on the matter

I dont mean that tenure budget should not exist, i mean tenure block budget limit and fast block budget imit should exist at the same time

@hugocaillard
Copy link
Collaborator

@siriusbtc currently there's only a tenure budget. Can you explain what you have in mind with the addition of a block budget?

@eriqferrari
Copy link

@siriusbtc

there are more bitcoin blocks times exceeded 10 mins than we imagine

There's the tenure-extend strategy for that, where the miner gets a fresh new budget to keep mining.

why not considering to automatically extend the tenure with a new budget, every time the block size is 99% allocated?
Miners will continue to produce blocks until the next tenure is minted. this way high fee tx will always be confirmed immediately, but the network can respond to high demand when it's needed.

@siriusbtc
Copy link

siriusbtc commented Oct 31, 2024

@siriusbtc currently there's only a tenure budget. Can you explain what you have in mind with the addition of a block budget?

The benefit of setting budget limit on fast blocks when setting a big tenure budget is that could make stacks fasts blocks always achieve 5 second in any cases of bitcoin block time gap, and could be fully filled with txs on stacks super high volume flow scenario.

For example, the tenure size limit is 1GB, fast size limit is 500KB, on the most extreme case that bitcoin block get 2 hours interval, stacks mempool has 1M pending txs, 2•60•60=7200s,7200s/5s=1440 fast stacks blocks, 1400•0.5MB=720MB<1GB tenure limit, stacks network could meet this challenge.

The design of big tenure block budget and small fast block budget could make stacks generate 5 second blocks smoothly and solve congestion in any cases

@jcnelson
Copy link
Member

jcnelson commented Oct 31, 2024

Tenure limits are no longer relevant in Nakamoto, since signers decide how many tenure extensions can happen per unit time. The "tenure limit" parameter only controls how much compute resources get consumed between TenureChange transactions (be they Extension or BlockFound). In the extreme, Nakamoto's runtime limits only require that each transaction fit into the "tenure limit" constraints, since signers could grant an Extension every block, and every block could contain just the Extension and the humongous transaction.

That said, a per-tenure size limit of 1GB is unsustainable, even in the short term. It would mean the blockchain grows by about 1 TB a week, which is well beyond most people's storage and bandwidth budgets.


I agree with @obycode that the signers ultimately need to meter the miners' resource consumption. We can't leave this to miners. The economically optimal strategy for miners it to greedily fill their tenures with all available transactions as soon as possible, since they do not know when the next Bitcoin block will arrive, they don't know if more-valuable transactions will arrive before their tenure ends, and any transactions they don't mine are transactions that will be picked up by the next miner. So, signers have to throttle them down.

We want to preserve the property that Nakamoto provides low transaction latency to those who are willing to pay the tx fee for it. At the same time, we also want resource consumption rate to be linear as a function of time in expectation -- if you're X% the way through the tenure, then X% of a given resource ought to have been used. To support both, I think signers need to allow a miner to exhibit some bursty behavior as a function of the transaction fee and the degree of burstiness. If they have a humongous transaction with a very high fee, then signers should allow them to mine it right away (recall that signers are incentivized to maximize miner ROI because it maximizes PoX payouts). But, that fee needs to be high enough to justify deviating from the targeted resource consumption rate. The more deviation, the higher the fee (in fact, the required fee probably needs to grow faster-than-linearly with the degree of deviation).

@eriqferrari
Copy link

Hi @jcnelson, I have some questions about the overall UX:
which TPS should we expect for Stacks considering the actual tenure limits?
how can we scale in case of high demand to have a seamless Bitcoin DeFi?
there could be more than one tenure-extend before the tenure change?

hope you will activate the tenure-extend function asap, this could at least increase 2x the max TPS

@benjamin-p-newton
Copy link

benjamin-p-newton commented Oct 31, 2024

My 2 cents.

Upfront I'll note that I'm not a Stacks developer and nor do I fully understand the mechanics or limitations of a Stacks tenure (given @jcnelson's recent comment above). None-the-less, hopefully my thoughts spark some thought and is somewhat helpful.

Rather than limiting a Stacks tenure to a X resource unit (RU) budget, along the lines of what @siriusbtc is suggesting, why not limit the Stacks blocks themselves to a Y resource unit (RU) budget (Y being a fraction of X)?
Bitcoin blocks on average occur every 10 minutes, for the sake of argument let's assume we're targeting a Stacks block every 5 seconds. That means a Stacks tenure would need to produce 120 blocks on average. For the sake of argument lets assign X a value of 120 resource units (RUs) and Y a value of 1 resource unit (RU).

If Stacks blocks were limited to a 1 RU budget, some miners would be caught short if a Bitcoin block arrived early, some miners would win big if a Bitcoin block arrives late, but on average over the long-term miners would be able to utilise the full 120 RUs per Stacks tenure/Bitcoin block (and make on average the same fees as they would currently over the long term).

Meanwhile, Stacks blocks are being produced at a consistent and reliable frequency to allow for a predictable UX for end-users.
Additionally, to make the system more dynamic, if the network is able to produce Stacks blocks faster than every 5 seconds, lets say 3 seconds, the protocol could adapt and change the Stacks block budget to a smaller RU to increase the frequency of Stacks block production (while maintaining the Stacks tenure budget).

In the case that a single transaction exceeds the Stacks block budget (not even sure if this is reasonable under current circumstances) and if the miner choses to mine the single transaction in the block (due to a lucrative fee), then the subsequent Stacks block budgets are reduced until the deficit is restored and normal Stacks block budgets can continue. Thus, maintaining the average Stacks tenure budget (over the long term).

Once the consistent frequency and reliability of Stacks block production is resolved, then well considered throughput optimisations can be made. For example, if the single Stacks block resource budget is continually exceeded by individually large and resource intensive transactions, then maybe it's worth looking at increasing the Stacks block budget. Plus, all the other optimisations that have already been highlighted, etc.

@owenstrevor
Copy link

owenstrevor commented Nov 1, 2024

Make the budgets bigger. Other optimizations are just putting a band aid over the problem. Developers and end users will not use an L2 that is slow and we are so early in the adoption cycle that these tiny budgets don't make any sense.

@tycho1212
Copy link

tycho1212 commented Nov 1, 2024

@owenstrevor gets it, accelerate

@yinyunqiao
Copy link

yinyunqiao commented Nov 4, 2024

@siriusbtc currently there's only a tenure budget. Can you explain what you have in mind with the addition of a block budget?

Would also like to know, what's the technical reason behind the design on the budget at tenure level, not fast block level ? If technically possible to have per block budget limit, we seems don't need tenure level budget nor the tenure extend thing, miners should be able to produce fast blocks as big as they can as long as the blocks are within the limit, and produce blocks as many as they can until next bitcoin block mined. Are there any special reasons to make stacks can't do this way due to the nature of stacks' PoX and deep binding with Bitcoin network ?

@muneeb-ali
Copy link
Member

I think we need to look at both cost function updates (requires a hardfork but we might need to do a hardfork for a separate upcoming emissions SIP that is timely) and making tenure extensions happen more frequently. I don't think it was ever the intention of the nakamoto launch that only certain types of transactions (like transfers) will be fast and other types of transactions will not be. Core devs decided to ship the bulk of nakamoto live to derisk any further delays, get real-world data from mainnet, and now can focus on performance optimizations. There is nothing fundamental here that stops stacks from being fast relative to other L2s, just a bunch of tradeoffs and optimizations that we plan to focus on now.

@owenstrevor
Copy link

owenstrevor commented Nov 4, 2024

Hi all,

What I'm hearing here and in chats with several builders leads me to believe core devs and ecosystem builders are on dramatically different pages with their beliefs about the right balance between node requirements and network performance. Because of this, I believe there's a good chance the current upgrades being worked on will fail to meet the community's expectations and largely be a waste of time until these differences are reconciled—leading to further disappointment and frustration on both sides.

The first thing I'd recommend is for core devs be 100% transparent on what the actual cost functions and limitations are for block space, compute limits, etc. All that has been said so far is that tenure extension mechanism will add flexibility to adjust the budget dynamically. This statement lacks specifics. My hunch is that this flexibility is not unlimited and there is a likely scenario the mechanism will not include enough flexibility to address the the community's needs.

The second thing I'd recommend is to engage with builders on the logic and calculations behind these limitations. Hardware costs are actually very easy to model in the real world. We can almost say with certainty what the cost per GB of RAM and disk space will be 5 years from now based on 20 years of historical data. We can reliably extrapolate to say, "in 5 years, a $1,000 computer at BestBuy will have X RAM and Y disk space." Yet, to my knowledge no transparent discussion about the node requirements based on demographic data and hardware costs has been had and no one can answer to the logic behind the core devs decisions about network limitations. There's no reason this can't be boiled down to a single cost number for running a node backed by historical market data and a hardware/performance function. e.g. "For anyone to be able to run a node with at least $500 from 2024-2035, the block size/compute limits will be fixed at X without further software-level optimizations."

For Stacks to be the number 1 L2 on Bitcoin the balance between node requirements and network performance should not be guess work, nor should the decision be made devoid of feedback from the actual builders who know the competitive landscape they are operating in and what kind of performance they need/expect from Stacks for their businesses to be competitive.

Core devs have done a fantastic job getting Nakamoto across the finish line. Let's take the time to do the next upgrade properly so it meets everyone's expectations and we're not stuck going in circles here without addressing the core issue.

@hstove
Copy link
Contributor

hstove commented Nov 4, 2024

I think we need to look at both cost function updates (requires a hardfork but we might need to do a hardfork for a separate upcoming emissions SIP that is timely) and making tenure extensions happen more frequently

Building on this, if we only shipped an update to the cost limits, you'd see the exact same behavior as today (block budget filling up quickly in a tenure), it's just that the first block(s) would have more transactions in them. You'd still end up with only STX transfers being allowed until the next tenure (or tenure extend). Obviously it's not rational for a miner to spend 10 minutes building a block, so if the cost budget were that high, it would make economic sense for miners to chunk this out a bit (but still probably with some heavier front-loading).

Only doing tenure extends (say, hypothetically, every minute) would have the same behavior as today, but at least every minute you'd get through a lot more of the more expensive transactions.

So, ultimately I think doing both (increasing the cost budget as appropriate, and also implementing better ability for us to be flexible with when to do tenure extends) is needed.

There is also a balance here of aiming for very fast (ie 5 second) block times. Even if we shipped both tenure extends and cost budget increases, it may be the most fruitful path for miners to spend as much time as possible (up to some point) building one big block. For us to achieve 5 second blocks consistently, we may need signers to enact a "fast block cost budget", as some have mentioned.

@hstove
Copy link
Contributor

hstove commented Nov 4, 2024

All that has been said so far is that tenure extension mechanism will add flexibility to adjust the budget dynamically. This statement lacks specifics. My hunch is that this flexibility is not unlimited and there is a likely scenario the mechanism will not include enough flexibility to address the the community's needs.

Ok, to be specific, here is the upper bound:

  • The current cost budget is X
  • A miner fills a block up to X
  • Signers approve it and the block is mined
  • Miner starts over but with a TenureExtend, which signers are OK with, repeat

(This scenario is essentially the same as setting a "fast block budget")

@muneeb-ali
Copy link
Member

My hunch is that this flexibility is not unlimited

Yes, it's not unlimited. It's a reset of the existing compute budget. And the reset can only happen after X time has passed. @hstove does a good job explaining this above.

So, ultimately I think doing both (increasing the cost budget as appropriate, and also implementing better ability for us to be flexible with when to do tenure extends) is needed.

This nails it. You need both and just one of the two won't be enough.

@eriqferrari
Copy link

@muneeb-ali Since the hard fork requires more time to be implemented, do you think the tenure extension mechanism could be activated within two weeks, and block size increased in 3 month, SIP voting included? it's a reasonable schedule in your opinion?

@owenstrevor
Copy link

1 more thing—In addition to an analysis on hardware cost, it would be helpful to look at the activity on L1 for Runes/Ordinals/BRC-20 over the past year as a benchmark for what kind of network activity we would need to be able to accommodate on Stacks.

@yinyunqiao
Copy link

All that has been said so far is that tenure extension mechanism will add flexibility to adjust the budget dynamically. This statement lacks specifics. My hunch is that this flexibility is not unlimited and there is a likely scenario the mechanism will not include enough flexibility to address the the community's needs.

Ok, to be specific, here is the upper bound:

  • The current cost budget is X
  • A miner fills a block up to X
  • Signers approve it and the block is mined
  • Miner starts over but with a TenureExtend, which signers are OK with, repeat

(This scenario is essentially the same as setting a "fast block budget")

So why this TenureExtend thing was designed in the first place ? I tried to dig up the answer myself but couldn't find it. Almost all other blockchains are designed with per block limitation, include Bitcoin. If Worrying the block are filled too full, then just put a relative smaller limit per block wise. It's almost like before people cooking every dinner they must ask for permission from the government. Can someone point me some reasonable technical analysis behind the design please ?

@owenstrevor
Copy link

All that has been said so far is that tenure extension mechanism will add flexibility to adjust the budget dynamically. This statement lacks specifics. My hunch is that this flexibility is not unlimited and there is a likely scenario the mechanism will not include enough flexibility to address the the community's needs.

Ok, to be specific, here is the upper bound:

  • The current cost budget is X
  • A miner fills a block up to X
  • Signers approve it and the block is mined
  • Miner starts over but with a TenureExtend, which signers are OK with, repeat

(This scenario is essentially the same as setting a "fast block budget")

How much is X?

@muneeb-ali
Copy link
Member

@muneeb-ali Since the hard fork requires more time to be implemented, do you think the tenure extension mechanism could be activated within two weeks, and block size increased in 3 month, SIP voting included? it's a reasonable schedule in your opinion?

Tenure-extend can be faster for sure because doesn't require a hardfork. The only reason I'm pushing for updating cost-functions is that (a) they likely give a higher performance boost and (b) there is likely a timely hardfork coming up (early Dec), see this emissions post and the cost functions can be updated with the same hardfork vs waiting a longer time for it.

@FredCat32
Copy link

Lets say we do the tenure extend and update cost functions in early December. Do we have any estimation as to what the results of that would be?

From my understanding, simply extending tenure wouldnt fix the issue of blocks being filled instantly right? Miners would still want to fill instantly so as to not leave any money on the table.

@hstove
Copy link
Contributor

hstove commented Nov 5, 2024

@owenstrevor this is the cost limit:

{
    write_length: 15_000_000,
    write_count: 15_000,
    read_length: 100_000_000,
    read_count: 15_000,
    runtime: 5_000_000_000,
}

https://github.com/stacks-network/stacks-core/blob/develop/stackslib/src/core/mod.rs#L207-L213

Comparing with L1 isn't really 1-1 because Bitcoin only accounts for data (there is no "compute" cost), but this roughly equates to 15MB of written data per tenure, which is the only really comparable metric to L1.

@hstove
Copy link
Contributor

hstove commented Nov 5, 2024

I'd like to personally thank everyone (especially non-core devs) in this thread for chiming in and taking the time to understand the problem and the possible solutions - IMO this has been a pretty productive discussion, even though I know many of you are frustrated about the current experience. There will be disagreements about what the exact solution should be, but I think we're all on the same page in terms of how we want this to improve from a user experience standpoint.

@owenstrevor
Copy link

owenstrevor commented Nov 5, 2024

@owenstrevor this is the cost limit:

{
    write_length: 15_000_000,
    write_count: 15_000,
    read_length: 100_000_000,
    read_count: 15_000,
    runtime: 5_000_000_000,
}

https://github.com/stacks-network/stacks-core/blob/develop/stackslib/src/core/mod.rs#L207-L213

Comparing with L1 isn't really 1-1 because Bitcoin only accounts for data (there is no "compute" cost), but this roughly equates to 15MB of written data per tenure, which is the only really comparable metric to L1.

This is super helpful! Thanks Hank. This should give builders a starting point to work with and estimate a few scenarios for what kind of throughput they realistically need.

100% understand the L1 and L2 have very different data/compute models. The founders I've talked to are looking to estimate the costs of their various smart contracts calls and compare that to the number of Txs on L1. So if you're building a swap on Stacks, you would look at the number of L1 swaps on Runes per block during different situations. Then you would multiply that by the % of market share you expect (let's say 10% market share) and then multiply that number by the cost of that specific smart contract call for your app on Stacks. Do this a couple times for different use cases and this can help you estimate what kind of throughput is needed. However, I'd guess that with faster blocks and lower fees the same people would have more activity so we could throw in another 25% bonus multiplier to account for that.

@vini-btc
Copy link

vini-btc commented Nov 6, 2024

I've added a new visualization to the quick block space usage I shared above. I also extended the data so that there is data for block budget utilization from block 1000 until 172661, grouped by tenure.

This, for example, shows % utilization per dimension in the few blocks after Nakamoto was activated and the mempool was quite busy:

untitled (1)

You can navigate and interact with the data here: https://observablehq.com/@vini-btc/stacks-space-usage

I still haven't validated/cleaned it up, so it could be off. Something I found peculiar is that a few tenures after Nakamoto already seem to show read count consumption above the tenure limit. Tenure 172299, for example, seems to have used ~30.000 read counts, and 172480 almost ~45000. I'm not sure if this is expected or not.

I am, anyway, sharing in the hope it could be informative now and in the future.

@eriqferrari
Copy link

First i want to thank all the core devs for the hard work!
i would like to focus how block size is calculated. as many members pointed out in the previous posts the real bottleneck are the read counts. this is impacting negativily the real permorfance of stacks, allowing only stx-transfer to be fast confirmed at the end of a tenure.

But as @hstove pointed out the only metric applicable to Bitcoin L1 is the size of write operations.
in this very simple example of an ft mint operation we can clearly see the negative impact of read counts. agaist only 1byte of written data we need 5 read counts operation.

>> ::get_costs (contract-call? .fungible-token mint u1000000000000 tx-sender)
+----------------------+----------+------------+------------+
|                      | Consumed | Limit      | Percentage |
+----------------------+----------+------------+------------+
| Runtime              | 5883     | 5000000000 | 0.00 %     |
+----------------------+----------+------------+------------+
| Read count           | 5        | 15000      | 0.03 %     |
+----------------------+----------+------------+------------+
| Read length (bytes)  | 2357     | 100000000  | 0.00 %     |
+----------------------+----------+------------+------------+
| Write count          | 2        | 15000      | 0.01 %     |
+----------------------+----------+------------+------------+
| Write length (bytes) | 1        | 15000000   | 0.00 %     |
+----------------------+----------+------------+------------+

so my suggestion is to focus on the write length of the tenure, instead of limiting it's capabilities when read count are too high. Understand we need to keep execution cost predictable not allowing infinite read counts, but to fill up 15MB we could raise read counts at 150k. Increasing the block size is the best option, but also remodulating the way the bugdet costs are calculted will allow to have tenure sizes near to the max allowed, optimising users performance and profits for miners.

see you later at the AMA

@benjamin-p-newton
Copy link

benjamin-p-newton commented Nov 7, 2024

I'm still a little unclear, and I'm hoping someone can clarify for me.

Is the idea that tenure extend will be used every stacks block, so that each stacks block has a consistent throughput?

For example, with the current budgets the second stacks block in a tenure is stuffed with 50-100 transactions and then subsequent stacks blocks trickle through with 1-3 transactions at varying intervals until a bit coin block presents and a new stacks tenure is ushered in.
With tenure extend, will each stacks block (at current budgets) be able to process 50-100 transactions at a reliable frequency (5-10 seconds), or will tenure extend be activated every few minutes or so?

If tenure extend can only be activated every few minutes or so, are there any solutions in discussion for ensuring that each stacks block arrives at a consistent interval (eg. 5 seconds with reasonable margin for error) with a consistent throughput per stacks block (eg. 50-100 transactions w/ current block budgets)?

@yinyunqiao
Copy link

I'm still a little unclear, and I'm hoping someone can clarify for me.

Is the idea that tenure extend will be used every stacks block, so that each stacks block has a consistent throughput?

For example, with the current budgets the second stacks block in a tenure is stuffed with 50-100 transactions and then subsequent stacks blocks trickle through with 1-3 transactions at varying intervals until a bit coin block presents and a new stacks tenure is ushered in. With tenure extend, will each stacks block (at current budgets) be able to process 50-100 transactions at a reliable frequency (5-10 seconds), or will tenure extend be activated every few minutes or so?

If tenure extend can only be activated every few minutes or so, are there any solutions in discussion for ensuring that each stacks block arrives at a consistent interval (eg. 5 seconds with reasonable margin for error) with a consistent throughput per stacks block (eg. 50-100 transactions w/ current block budgets)?

I have asked the same question twice but haven't got direct answer yet , really appreciate someone with enough knowledge to give some comments on this!!!

@vini-btc
Copy link

vini-btc commented Nov 7, 2024

@yinyunqiao @benjamin-p-newton, I had the same question. This comment and the thread helped me understand some of the possibilities and drawbacks of the tenure-extend approach: #4316 (comment).

After reviewing what was said there and in this thread, I understand that it alone can't get us to consistent 5-second blocks, but it can help improve the throughput.

The critical issue is you can't rely on it running continuously at 5-15 seconds since it would effectively be the same as increasing computation budgets. So you'd have to rely on it to work consistently but at shorter intervals (@obycode suggested 1 minute?), which would mean we would still see the same behaviour where the first blocks are filled quickly but you'd wait less for the next burst of blocks or we could have some heuristics to determine when to increase the pace.

This last one would still be tricky to implement and work properly IRL. The heuristic would probably have to be a proxy for "mempool business," something like "if the mempool is busy, emit shorter tenure extensions to increase compute budget temporarily." If we do that, and it works, and everyone gets excited, the mempool could start becoming consistently busy, which would require the mechanism to be consistently in play, and we would end up in a situation where computation budgets were increased indirectly.

Ultimately, the solution to consistent 5-15 second blocks must involve a mechanism where miners are forced to fill their compute budget evenly throughout their tenure - a few ideas on how to achieve it were shared here. Doing this with current budget limits would lead to a situation where 5-second blocks are there, but fees would be very high, so the chain is fast for those who can pay for its fastness. So, in the end, we'll inevitably need to revisit computation budget limits, which is why I've insisted we at least adjust the read-related counts. It was already verified (#4316 (comment)) that were initially set too pessimistic, and they'll probably have less impact on node bootstrap time and block processing time and they've been consistently the biggest bottleneck in terms of computation budgets (see the data and visualizations I've shared above). More considerable read limits + 1-minute tenure extensions would give a decently fast experience for most while core works on a proper final solution for spreading computation usage throughout tenures. And since it is a "fix" to a wrong original estimation, there shouldn't be a need for too much debate, and we could perhaps include it in the next hard-fork.

Edit: fixed grammar

@benjamin-p-newton
Copy link

@vini-btc, thank you. Very helpful.

@yinyunqiao
Copy link

@vini-btc thank you very much. I understand now with current 'tenure-extend' design, we can only make the interval of extend shorter, but not consistent fast block level result. The only remain question I have is what is the real reason the 'tenure-extend' was designed ? Why not design the block limit like all other blockchain to just put a upper limit on every block level ?

@benjamin-p-newton
Copy link

@yinyunqiao, @jcnelson mentions here how a 'stacks block limit' may be implemented irrespective of tenure extend logic.

@jcnelson
Copy link
Member

jcnelson commented Nov 8, 2024

@yinyunqiao Apologies for the delay; we've all been busy trying to put this and other fires out.

Nakamoto differs from Stacks 2.x and many other blockchains in that it decouples the notion of resource consumption from the notion of blocks. It treats blocks solely as a data frame and checkpoint mechanism -- blocks are lists of one or more transactions (the data frame), and a header that, among other things, contains plus a state root hash signed by signers and the miner (the checkpoint). By doing so, it enables the system to set its own target resource consumption rates independent of block production, which enables the system to respond in real-time to ever-changing computing needs regardless of what the chain is actually doing. For example, if a faster version of the Clarity VM is released, the resource consumption rate can be bumped up right away to allow that extra capacity to be consumed by more user transactions. As another example, if there was ever a burst of network activity (e.g. a big NFT drop), the consumption rate could be temporarily bumped to quickly process the burst.

Specific to Nakamoto, signers decide and enforce chain quality-of-service rules. The observed resource consumption rate is a derived value from the rate at which signers allow miners to consume it. Because resource consumption is treated separately from blocks in Nakamoto, it can be expressed as policy logic, not consensus logic -- the signer and miner operators will coordinate out-of-band to produce blocks that meet an agreed-upon consumption rate without the need for a hard fork (as was the case in Stacks 2.5 and earlier).

This yields a very flexible system design. Signers' policies on resource consumption can be parameterized on arbitrary properties of the system, tailored to meet the needs of the day in ways that no one has even thought of yet. For example, signers might agree with miners that any block comprised solely of stacking transactions will automatically get a tenure-extension, thereby making stacking transactions "free" from a resource consumption perspective. As another example, signers might agree to refuse to sign a block that uses too many resources too quickly ("throttling" them), in order to force miners to give users a chance to submit (or RBF) their transactions mid-tenure and get them mined in the next block.

The TenureExtend transaction is needed by the consensus rules to allow signers to reset the current miner's tenure's resource consumption to date. This is the building block with which signers decide and enforce maximum resource consumption rates. Beyond this, signers implement and enforce chain QoS policies to refine resource consumption rates as they please. Importantly, signers are incentivized to implement QoS policy that helps miners get the best STX/resource trade-off they can get, since that maximizes PoX yield for signers.

There are of course a myriad of ways to address this problem. The reason we chose to make a special TenureExtend transaction which miners submit is that it provides a direct way for miners and signers to late-bind on what the resource consumption will be. Signers don't need to coordinate with miners on what the resource consumption needs to be until miners ask for it. This is ideal since miners, by virtue of the fact that they produce blocks, are the first nodes to realize the need for higher resource consumption rates.

Hope that clears a few things up. Happy to answer more questions as time permits (but again, apologies in advance if it takes a few days for me and the others).

@yinyunqiao
Copy link

yinyunqiao commented Nov 9, 2024

@jcnelson thank you very much for the detail explanation, it's very helpful. Although I still have so much questions about the design and how it works in practice ... but I think I might need to dig the actual code a bit deeper before asking more questions.

Please keep up the good work guys, also would anybody share some estimate when this #5398 issue can be included in the next minor releases please ? Maybe Stacks people have been stuck with Bitcoin's unstable 10 minute block time for too long, so most of the community are more than happy to the current condition. But to be honest for most of other blockchains there, occasionally block producing stopped for 10+ minutes even > 1 hour is disaster level problem.

This really shouldn't necessarily be the case after years of hard working ... If the design's goal is flexible and can be quicker to response, this is the time to show the strength of this unique design.

@hiddentao
Copy link

Just to point out one thing that might not be immediately obvious -- the challenge to simply raising the block budget (or allowing unlimited tenure extends) is that the larger this total budget is, the more difficult it becomes to boot a node from genesis (i.e. a node booting up needs to replay the same transactions significantly faster then real-time, or it will never be able to catch up to the tip), so we have to be careful not to go too high with that total budget.

I wouldn't worry about this so much. Other blockchains have already had to solve this issue and usually it comes down to downloading the block history from another node without needing to replay transactions. Of course, this implies a trust assumption. But that's solvable heuristically - e.g one could download history from one full node and then run validation checks against the data by querying another full node and/or download the history in chunks from multiple nodes and use a merkle hashtree to verify correctness.

@314159265359879
Copy link

I think flexible expiration times (think 30 seconds to a minute or one tenure) for transactions could help incentivize miners to include transactions that have high fees quickly. A way to enforce Quality of Service in a sense.

It is not entirely on topic for this discussion so I put a brief here: https://forum.stacks.org/t/stacks-block-and-tenure-dimensions-expectations-and-discussion/17665/19?u=werner1

@obycode
Copy link
Contributor Author

obycode commented Dec 13, 2024

Closing this thanks to #5450 and #5530!

@obycode obycode closed this as completed Dec 13, 2024
@github-project-automation github-project-automation bot moved this from Status: 🆕 New to Status: ✅ Done in Stacks Core Eng Dec 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Status: ✅ Done
Development

No branches or pull requests