CHIP-2025-03 Faster Blocks for Bitcoin Cash

Anything that is evaluated against a block span:

  • nSequence (user-set span)
  • coinbase maturity (span of 100)
  • halving (span of 210k)
  • parking depth (span of 4)
  • finalization depth (span of 10)
  • ASERT (span between anchor and tip)

With ticks, they all smoothly transition through the block time change boundary. No complicated expressions inside individual mechanisms, e.g. nSequcence enforcement is simply "an input is mature in block b if T(b) - T(c) >= 600 * n", where T(b) is the block’s tick value, a pure function of b’s height.

Tick mapper handles T(x) by checking the set tick schedule (just 1 row for our 1st switch 600->60; {H_a, 60}).

2 Likes

FWIW, This comment alone is probably as or more compelling than the current alterntative text in the CHIP. That is to say very compelling.

3 Likes

see updated section :slight_smile:

Just to provide a counterpoint – conceptually to you these are simple because you can unify them with ticks.

To someone that has to implement this – it’s like a NUKE went off in the codebase. Everything got touched.

In practice all that code got hard raped by all the changes. It’s a huge codechange either way. From my perspective as a developer I would have preferred to not rape the following things:

  • Coinbase maturity. Leave it as a height of 100. Scaling it to 1000 is confusing and surprising.
  • Block size. Don’t touch it. Marrying ticks into ABLA feels like incest. Leave it at 32mb blocks every minute. We should be so lucky if we get that much traffic.
  • nLocktime – the height mode should STAY as height. If you meant TiME, you should have used TIME mode, not HEIGHT mode. What the CHIP proposes creates a lot of developer confusion. Good luck calculating nLocktime now if you are a lowly app developer…
  • nSequence – same argument as nLocktime
2 Likes

But my point is that without ticks the same everything would’ve had to be touched – just touched in a different way (inline the arithmetics).

Your list is not an argument against ticks, but argument against touching some places at all – by preserving raw height instead of another invariant (e.g. TPS, target wall clock time).

1 Like

You didn’t read my point.

My point is you touched more than needed to be touched. See my list above where I would have been ok with not touching.

You define the list of things that needed to be touched but that’s a matter of opinion, really, not a hard requirement.

My list was smaller and didn’t need ticks.

What you did was marry lots of stuff now to PoW in a way where it wasn’t explicitly married before. Including block size! Including nLocktime/nSequence!

Is that a good idea? Debatable. Not a given. You think it’s a given, I get it.

We don’t all think that way.

2 Likes

I get your point, just saying it’s orthogonal to ticks. But yeah, you just cutting the list shorter would have reduced the surface and thus reduce relative payoff from ticks.

But should we cut the list? CHIP defends the list. e.g. 2q_x’s apps have >1k BCH TVL and they depend on NOT having height locks unlock earlier than expected.

1 Like

The payoff for ticks would be if we anticipate adjusting the blocktime further in the future. And if we want to marry as much as got married to PoW as you are marrying in this chip.

Minimally I think nLocktime and nSequence should be left alone and still mean height in height mode.

If some contract was using height as a proxy for real world time, when there already is a TIME mode, that’s on the contract.

I think it makes it incredibly hard to reason about things as an app developer to redefine nLocktime the way you have to be some “abstract height in some abstract space where blocks were still 10 mins”.

I get the motivation behind it – you can repeat it to me autistically… but my argument holds.

It’s confusing and makes nLocktime/nSequence very difficult to work with.

Of all the things in this chip – the modification of nLocktime to have a changed meaning is the one I like the least.

3 Likes

He should fix his contracts then. If he cares about time he should use time mode.

Don’t we? Removing the obstacle to further reduction was actually a big thing that helped the CHIP get through.

Me too, because it’s one place where you can’t have it both ways.

Our contract developers don’t seem to have a problem with it. CashScript can abstract this nicely.

2 Likes

I never said we didn’t. Just clarifying that ticks buys us that.

I still think it doesn’t need to be married to blocksize at all. But we have small pee-pees and are afraid to do 32MB blocks every minute… so what can we do?

We marry ticks (and thus PoW) to blocksize, lol.

3 Likes

I mean we had this simple thing – if you care about height, you get height. If you care about time, you can use time.

Now it’s both time. Just weird gay time and normal unix time.

Meh.

3 Likes

The semantics of nLocktime and nSequence are actually the most annoying part of consensus spec. I wish to clean this up one day if we change TX format. Imagine an alternative input field: 2-bit bitfiled + 62-bit integer. You say exactly what you want:

  • block count (or index)
  • tick span
  • real time (MTP)
  • relative or absolute? (since genesis or since coin creation)

and put the number in the 62-bit part.

2 Likes

Even if you do that – Some smarty pants comes along and locks 1K BCH in some contract that uses that as a proxy for wall-clock-time WHEN TIME ALREADY EXISTS AS A THING IT CAN EXPRESS (he just likes height).

And so we want to change blocktime again – do we rescale it then too?

You see what I’m getting at here?

We are making nLocktime hostile to devs now. What nLocktime should I use if I care about fee sniping in the year 2040 when subsidy is very low and fees pay for everything?

I guess I have to calculate it – it’s not obvious. (height - SOME_CONSTANT) / 10 + SOME_CONSTANT.

Not an impossible formula. Just confusing.

1 Like

It’s not through yet since implementation is a nightmare for me. EVERY TEST BROKE.

2 Likes

Of course it did, because it’s a good test. And I understand the whole burden is on your shoulders now, and it gets hard and frustrating. We could task some AD to help you, but I know you don’t want that. :slight_smile:

“We choose to go to the Moon in this decade and do the other things, not because they are easy, but because they are hard.”

It’s hard watching LTC take our traffic. It’s hard listening to same “when block” complaints over and over again… we do this hard thing now – we will forever remove a lot of other hards.

That’s one way to look at it. The other way is: height-based locks are a proxy for chainwork (e.g. in cross-chain swaps). There’s no way to express chainwork with time-based locks, because setting a 30-min lock is no guarantee you get 3-conf worth of security: you could only be getting 1 due to variance. You could counter that by saying, well, these short-lived contracts will unlock anyway, and then they can set their locks to 30 (with 1-min blocks). But - live immutable contracts that carry the same height lock over (e.g. some oracle auto re-locking with nSequence=1) would start to have 10x more frequent updates through no fault of their own.

2 Likes

No. Legacy locktime “height” will forever map to the concept of a 600-ticks “chunk”, where chunk_index = tick / 600. Exposing ticks makes calculating the chunk easy, because you don’t need to know about underlying block time changes.

1 Like

Nobody but some niche nerds will think in terms of “chunks” ever.

You missed my point entirely.

The same argument being made now to scale nLockTime in height mode can be made in some hypothetical future: “b-b-b-ut there is this 1 contract that will break that was just using height when it really wanted wall-clock-time”…

My problem with the nLockTime redefinition is that it is just that A REDEFINITION.

For people that knew what nLockTime was – the warnings were always there – don’t rely on it in height mode to mean time. For that we give you time mode. (For chain work – we don’t offer that. The chainwork argument is weak because it’s not coupled to chainwork in any strong or guaranteed way.)

nLockTime was defined as:

Height (if it's < 500,000,000), or nMedianTimePast (if >= 500,000,000)

You are redefining it.

Yes or no – 1 word answer only – is nLockTime being redefined by your CHIP or not? One word answer only: yes or no.

1 Like

Height and chainwork are loosely coupled at best. For short enough values of height changes, the coupling is there. For larger values there is no guarantee and it deviates completely because of price/hash/etc being unpredictable into the future.

Your redefined nLocktime certainly appears to couple them with intent now. It still fails. All you do is add complexity with no coupling anyway.

What is the point of this? DAA slips and slides all over the place. Is a 1000 height difference any guarantee of any amount of chainwork? ASERT half-life is 2 days. In 1000 blocks chainwork can be like hundreds of times smaller than you thought it would be.

Not much of a proxy for chainwork, even with ticks.

My point is the redefinition of nLockTime is kind of useless in practice. It just break things – in the interests of 1 contract you cite out there (really can I get a source on this??) that was using height mode when he should have been using time mode.

All I know is a handgrenade went off in my codebase and this implementation is very very very invasive, due to all the extra attempts at paving over things.

1 Like

Look, I’m not against the CHIP, I’m not even really against nLockTime being redefined.

I just peruse this message board and I see 1 side arguing like a salesman – and that’s fine. I think it would be devastating at this point to the community if this were not to activate either now or 1 year from now.

And I think we should do it.

I just want us to be adults and acknowledge that certain compromises had to be made and nothing is perfect.

There is a certain quality about what we are doing that does feel to me like we are defacing the chain. The nLockTime/nSequence redefinition in particular is the one that sticks out the most to me of all of them. Something just feels wrong about the redefinition. A simple idea that even dummies can understand now is… somewhat unapproachable.

But – the purpose of my debate with you was not to be “right” – just to illustrate that compromises were made, and they were made in the interests of preserving maximal economic guarantees (as we imagine them) to users of the chain – so that the upgrade breaks just software but not any money properties (as best as we can do here).

That’s all.

It’s no panacea. Compromises were made. There are casualties now. It’s not perfect. It’s just the best we (you) can think of in terms of not violating any UTXO (even hypothetical ones) in favor of violating software.

I think your CHIP also mentions this – we violate software but keep chain integrity integral.

I think this needs to be emphasized more.

Reading this thread it sounds like to me that you are presenting ticks as a “simplification”.

They can be argued to add complexity – to support this simplification – which is really an abstraction layer – there is more complexity added to the code and to the node.

It’s simpler in some terms… but more complex in other terms.

Layers of abstraction always are like that.

But they buy you flexibility…

6 Likes