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.
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.
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.
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?
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)
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.
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.
“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.
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.
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.
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.
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.
You’re right that DAA can change things over long horizons, but remember Bitcoin’s DAA would be flat for ~2 weeks, so even Satoshi initially used count as proxy for work, and later had to replace “longest chain” with “heaviest chain.”
Yes, it is. All this time height was in a meta-superposition: it both measured count and blockchain progression. Now we’re forcing it to collapse to progression, because collapsing to count would have worse consequences. Which invariant does this preserve? For relative locks and maturity — the rules where “count” was doing chainwork-equivalent work — it preserves how many coinbases’ worth of break-even security a unit buys: N units = 600N ticks = N coinbases, exactly. For absolute nLocktime it preserves progression: one unit stays ten nominal minutes — which in our no-backlog reality also means ~N coinbases worth of security.
Yes, it’s a compromise, and I agreed that makes locktime/sequence the ugliest part of this proposal because it forces us into compromise. At the same time, I argue that making the compromise will have future payoffs: we can change block time again and again, having already paid all this cost.
Yes, we’re making the compromise, and thank you for understanding why we lean on 10-min-units interpretation rather than plain count.
Yes, this is what it’s all about!
PS
1 contract you cite out there (really can I get a source on this??)
A simple idea that even dummies can understand
nLocktime / nSequence is anything BUT simple, look at ParyonUSD contract safety memo (which conveniently proves the claim there are existing contracts that depend on “chunk” interpretation – they use nSequence=12).
timelockRedemption is a hardcoded constant; the system’s docs mark everything but the oracle immutable. Under count-preservation that finalization delay silently becomes 12 one-minute blocks permanently — un-patchable, because there is no upgrade path. Under this CHIP it stays a 120-minute window, and the equality check never changes.
Relative Timelock Enforcement
Relative timelocks constrain how many blocks must pass between an input’s UTXO being created and the transaction spending it. Paryon uses this in one place: the 12-block delay on redemption finalization (redeem.cash, finalize branch), which pins tx.inputs[3].sequenceNumber == timelockRedemption.
Note that Paryon does not use this.age / OP_CHECKSEQUENCEVERIFY. The delay is enforced on input 3 (the redemption), not on the currently-evaluated input (input 2, the redeem contract), so CSV cannot be used and the check goes through raw sequenceNumber introspection instead. At that level there are two edges to handle explicitly:
Transaction version. BCH consensus only interprets sequenceNumber as a relative timelock when tx.version >= 2 (BIP68). Under version 1 the sequence field is just data and the 12-block delay would not be enforced by consensus: the script-level equality check would still pass, but the transaction could be mined immediately. redeem.cash therefore enforces require(tx.version == 2) alongside the sequence check.
Exact equality. The finalize branch pins the sequence with sequenceNumber == timelockRedemption rather than >= timelockRedemption. The sequence field carries a “disable” flag bit (bit 31) alongside the timelock value; a >= comparison would let an attacker set that flag, turning BIP68 off while still passing the script check. Exact equality rejects any extra bits.
Value range. BIP68 interprets only the low 16 bits of the sequence as a block count, so timelockRedemption must stay within 0..65535. A higher value would cause consensus to enforce a different delay than the script specifies. The current value of 12 is well inside this range.
PPS the oracle example was a hypothetical, but there’s a toy contract live: the Popcorn! stand - mint 50 tokens once per block: it carries forward nSequence of 1. Count interpretation would let it be minted 500 per 10 minutes instead of 50 as designed. I think there exist a few other token minters, with more value, that depend on same assumptions. Height mode is the only way to express a clean coupling to chain progression, and correct functioning depends on our redefinition to ten-minute units.