Bitcoin Development Mailinglist
 help / color / mirror / Atom feed
From: Anthony Towns <aj@erisian.com.au>
To: Rusty Russell <rusty@rustcorp.com.au>
Cc: bitcoindev@googlegroups.com, Julian Moik <julianmoik@gmail.com>
Subject: Re: [bitcoindev] [3/4] OP_TX
Date: Thu, 26 Mar 2026 18:30:39 +1000	[thread overview]
Message-ID: <acTurxiSsJCCY2gk@erisian.com.au> (raw)
In-Reply-To: <871phxaaac.fsf@rustcorp.com.au>

On Fri, Mar 06, 2026 at 02:17:55PM +1030, Rusty Russell wrote:
> Hi Aj,
> Sorry for the world's worst email latency, but I *am* replying!

This doesn't seem to have made it to the list? Original left quoted below,
in case this email makes it to the list.

On Fri, Mar 06, 2026 at 02:17:55PM +1030, Rusty Russell wrote:
> Anthony Towns <aj@erisian.com.au> writes:
> > On Sat, Sep 27, 2025 at 08:59:04PM +0930, Rusty Russell wrote:

> > I think it would be good to also have a selector:
> >
> >     TXSELECT_INPUT_OUTPOINT_HEIGHT
> > 
> > which pushes the height of the block at which the coin being spent
> > was confirmed. (In order to make that not terrible wrt reorgs, it
> > should also imply somewhere between "6 CHECKSEQUENCEVERIFY" and "100
> > CHECKSEQUENCEVERIFY")
> 
> That is a big implementation lift, adding a requirement to reevaluate
> on reorgs which I don't think existed before?

Having a requirement of a relative locktime of L=6 or 100 prevents needing
to re-evaluate it -- if the UTXO was at height H, and you're currently
at height H+L+K, then by the time you reorg back to H+L the spend is
no longer final and is removed from the mempool [0], so if you continue
reorging back to H-1 and then back up to H+L+K+1, you're re-evaluating
the entire transaction from scratch.

[0] In Bitcoin Core, this happens via the `filter_final_and_mature`
    function which is passed to `removeForReorg`, and checks
    `CheckFinalTxAtTip` (for locktime), `CheckSequenceLocksAtTip`
    (for relative locks) and checks maturity manually.

Because it can can cause previously valid spends to be invalid (rather
than just requiring a different ordering or later confirmation) after a
reorg, I think it's reasonable to apply a comparable sequence delay to
coinbase maturity, hence the 6-100 figure.

> It also creates the ability to have a kind of "fail after a certain
> height" transaction: your output scriptPubkey maps to a script which
> always fails if the blockheight of this tx is greater than some number.

It means that some of a UTXO's spend-paths can be observed to be invalid
at the time the UTXO is confirmed. That's a similar property to what
you get with signatures that can be rebound to different transactions
-- you might think that the stateN eltoo signature you have is good,
but then stateN+1 ends up confirmed, and it's not anymore.

It's obviously something you can simulate with multiple transactions:
you also can't spend an output that someone else has already spent.
So provided it's simple to handle efficiently in the mempool, I think
it's worth considering.

I think the "timeout is N blocks after commitment tx is published"
rather than "timeout is N blocks after the most recent response to the
commitment tx being published" is an important thing to be able to be
able to express, and so far this is my best idea for how to do that.

> I'd rather have a serious discussion on tx expiry, if we head in this
> direction.

I think tx expiry is largely a bad idea personally; it makes the most
sense for time-sensitive auction-like things which on-chain confirmations
are terrible at, it's more dangerous/confusing for recipients ("i
checked in mempool.space and the payment was on it's way, now it's gone
and i can't resubmit it??"), and I don't think it makes for that much
of an improvement for the things that it can enable (the HTLC expired,
now you can wait indefinitely to claim it, rather than needing to do
so immediately in case the other guy somehow gets the secret). I don't
think it can solve the "preserve-the-timeout-across-state-updates"
problem above.

I do think it could be implementable though; if a tx has an easy
way to indicate when it expires (specify the value N in the annex for
input spending utxo K, and your tx becomes invalid N blocks after K was
confirmed?), then when adding to the mempool you calculate max(K.height +
N) across each input, and add those values to your mempool index, evicting
txs as appropriate when your tip increases, and with a similar relative
timelock behaviour to also evict the tx from the mempool if you reorg
back close to K.height.

I think the TXSELECT_INPUT_OUTPOINT_HEIGHT is both easier to implement (no
additional index needed) and more powerful than simple tx expiry though.

Cheers,
aj

On Fri, Mar 06, 2026 at 02:17:55PM +1030, Rusty Russell wrote:
> Anthony Towns <aj@erisian.com.au> writes:
> > On Sat, Sep 27, 2025 at 08:59:04PM +0930, Rusty Russell wrote:
> >> ==OP_TX==
> >>
> >> OP_TX operates as follows:
> >>
> >> Examine bits in ''selection_vector'':
> >> - For each existing input ''i'' in the range ''first_input'' to ''first_input'' + ''num_inputs'':
> >>   - If TXSELECT_INPUT_OUTPOINT_HASH is set:
> >>     - output input ''i''s outpoint hash (32 bytes)
> >>   - If TXSELECT_INPUT_OUTPOINT_INDEX is set:
> >>     - output input ''i''s outpoint index (32 bits)
> >
> >>   - If TXSELECT_INPUT_SCRIPT is set:
> >>     - output input ''i''s script as a variable size object
> >
> > I think you should be clearer which "script" this is; it could be
> > the scriptPubKey (except you have a different selector for that), the
> > redeemScript from the scriptSig (except we haven't defined taproot outputs
> > for non-empty scriptSigs), or what this presumably is, ie the tapscript
> > v2 script from the witness. We have too many things called "script"...
> 
> It is kind of a hand wave, isn't it?  We probably *want* to ask "the
> script which will be evaluated for the given input".  That's the
> witnessScript for segwit, the scriptsig for pre-segwit, tapscript for
> taproot.
> 
> Ofc this is not defined for future output types (e.g. BIP 360).  But I'm
> unsure if should fail for those, return empty, or use the second final
> witness script and hope that convention survives into the future...
> 
> You can already examine the witness directly, but that's less convenient.
> 
> >>   - If TXSELECT_INPUT_AMOUNT is set:
> >>     - output input ''i''s input amount (64 bits)
> >>   - If TXSELECT_INPUT_SCRIPTPUBKEY is set:
> >>     - output input ''i''s scriptPubkey as a variable size object
> >
> > Shouldn't these be named TXSELECT_INPUT_OUTPOINT_{AMOUNT,SCRIPTPUBKEY}
> > (or COIN or UTXO in place of OUTPOINT) since they are obtained from
> > outpoint being spent, rather than directly from the input?
> 
> I like adding UTXO here.
> 
> > I think it would be good to also have a selector:
> >
> >     TXSELECT_INPUT_OUTPOINT_HEIGHT
> > 
> > which pushes the height of the block at which the coin being spent
> > was confirmed. (In order to make that not terrible wrt reorgs, it
> > should also imply somewhere between "6 CHECKSEQUENCEVERIFY" and "100
> > CHECKSEQUENCEVERIFY")
> 
> That is a big implementation lift, adding a requirement to reevaluate
> on reorgs which I don't think existed before?
> 
> It also creates the ability to have a kind of "fail after a certain
> height" transaction: your output scriptPubkey maps to a script which
> always fails if the blockheight of this tx is greater than some number.
> 
> I'd rather have a serious discussion on tx expiry, if we head in this
> direction.
> 
> > Providing TXSELECT_INPUT_OUTPOINT_WAS_COINBASE for completeness might
> > be worth considering. That could perhaps be useful for allowing things
> > like drivechains that give miners influence over coin movements to be
> > redesigned to not require additional consensus support?
> 
> Generalizing these gives allows a lightning-style short-channel-id-style location:
> BLOCKNUM-TXNUM-OUTNUM.
> 
> But I think this is a good reason to allow extension, which is why the
> proposal succeeds for unknown bits...
> 
> Thanks!
> Rusty.

-- 
You received this message because you are subscribed to the Google Groups "Bitcoin Development Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bitcoindev+unsubscribe@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/acTurxiSsJCCY2gk%40erisian.com.au.


      parent reply	other threads:[~2026-03-26 14:21 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-27  8:12 [bitcoindev] [0/4] A Bitcoin Scripting Proposal BIP Quartet Rusty Russell
2025-09-27 11:27 ` [bitcoindev] [1/4] Varops Budget For Script Runtime Constraint Rusty Russell
2025-09-27 11:28   ` [bitcoindev] [2/4] Restoration of disabled script functionality (Tapscript v2) Rusty Russell
2025-09-27 11:29     ` [bitcoindev] [3/4] OP_TX Rusty Russell
2025-09-27 11:29       ` [bitcoindev] [4/4] New Opcodes for Tapscript v2 Rusty Russell
2025-09-29 22:55         ` Brandon Black
     [not found]           ` <87seadabvi.fsf@rustcorp.com.au>
2026-03-12 18:00             ` 'Brandon Black' via Bitcoin Development Mailing List
2025-10-06 11:29         ` Anthony Towns
2025-10-06 11:41       ` [bitcoindev] [3/4] OP_TX Anthony Towns
     [not found]         ` <871phxaaac.fsf@rustcorp.com.au>
2026-03-26  8:30           ` Anthony Towns [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=acTurxiSsJCCY2gk@erisian.com.au \
    --to=aj@erisian.com.au \
    --cc=bitcoindev@googlegroups.com \
    --cc=julianmoik@gmail.com \
    --cc=rusty@rustcorp.com.au \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox