Author

Topic: Is it possible to let a transaction expire if it is not included in a block. (Read 276 times)

legendary
Activity: 3906
Merit: 6249
Decentralization Maximalist
I agree with garlonicon, vjudeu and tromp that an "expiration" via an opcode like the once-proposed OP_BLOCKNUMBER may not be feasible due to reorgs.

What may however be feasible is an "expiration command" which could be signed and sent by a node to the mempool at the block of the desired expiration, instructing other nodes to delete and blacklist the transaction from the mempool. Due to the signature, a censorship attack should not be possible. While it would not be 100% reliable (and thus not possible to be used in smart contracts) this would be already an improvement to now, e.g. when a deposit to a service expired and you want to prevent a confirmation in a low-fee period. The blockchain would not be involved at all so it would be reorg-safe.

Or is there something I'm missing here?

Also of course it should be simply possible to use RBF to replace the transaction at the deadline with one that returns the coins to yourself. Maybe it is even possible with nLocktime, so you can generate the "expiration transaction" already when you know when you want the original one to expire.
copper member
Activity: 821
Merit: 1992
Pawns are the soul of chess
Quote
I know there is a 200 block spending blockade for coinbase transaction for that reason. But that means you could apply the same logic for OP_BLOCKNUMBER.
It is different case. When you have 100 block maturity (not 200) of the coinbase transaction, it is always present, and always 100. But if you have a separate opcode OP_BLOCKNUMBER, then you can use the power of the whole Script and write any weird conditions, like "only Alice can choose how far from the current block number it can be". In case of OP_CHECKLOCKTIMEVERIFY it is not a problem, but in case of more generic OP_BLOCKNUMBER it could be very reorg-unsafe, because for one user it will have one block maturity, and for another user it could be 1000 blocks of maturity.
newbie
Activity: 24
Merit: 34
However, when I think about it I am starting to get doubts.
Because in case of a deep reorg, like what would happen in segmentation you will have the same problem because coinbase transactions will become invalidated and all coins that derive from them.
I know there is a 200 block spending blockade for coinbase transaction for that reason. But that means you could apply the same logic for OP_BLOCKNUMBER.
So it would actually be possible to do it.
sr. member
Activity: 1190
Merit: 469
He thought about it and he was asked specifically about it. You can find the reason in this topic: because adding transaction invalidation to the protocol is reorg-unsafe.

indeed it is. as you pointed out, satoshi addressed this issue wow that dude was on point Grin i didn't think about the reorg issue being a problem but satoshi did.
newbie
Activity: 24
Merit: 34
Thank you for this very interesting and insightfull answer!  Smiley
hero member
Activity: 813
Merit: 1944
He thought about it and he was asked specifically about it. You can find the reason in this topic: because adding transaction invalidation to the protocol is reorg-unsafe. Imagine Value Overflow Incident, where there are some transactions that are valid only before certain block number. Then, miners could ignore such transactions, and by not including them, they would also invalidate all transactions that were made later. Do you really want to find out that your previously-valid transaction is now invalid, because there were some kind of chain reorg, and some previous transaction was invalidated by such feature?
We can't safely do OP_BLOCKNUMBER.  In the event of a block chain reorg after a segmentation, transactions need to be able to get into the chain in a later block.  The OP_BLOCKNUMBER transaction and all its dependants would become invalid.  This wouldn't be fair to later owners of the coins who weren't involved in the time limited transaction.

nTimeLock does the reverse.  It's an open transaction that can be replaced with new versions until the deadline.  It can't be recorded until it locks.  The highest version when the deadline hits gets recorded.  It could be used, for example, to write an escrow transaction that will automatically permanently lock and go through unless it is revoked before the deadline.  The feature isn't enabled or used yet, but the support is there so it could be implemented later.

So, that means you cannot even have things like OP_BLOCKNUMBER, not to mention OP_BLOCKHASH proposed in decentralized lotteries. They are just reorg-unsafe, that's the reason, as you can read in the quote above.
sr. member
Activity: 1190
Merit: 469
I want to make a bitcoin transaction, but if it does not make it into the blockchain before a certain blockheight, I want the transaction to expire so that it can no longer be inserted into the blockchain. Is this possible?

As a layer 2 developer of Bitcoin I deem this capability very important and useful.

nlocktime makes a transaction valid only after a certain point in time. what satoshi forgot to put in was something called mlocktime which makes a transaction valid only before a certain point in time. wonder why. i'm sure he thought about it. must have had some good reason. maybe he didn't feel it was a useful feature?
legendary
Activity: 2352
Merit: 6089
bitcoindata.science
2. If you set very low fee (and didn't enable RBF) when mempool flooded with lots of transaction, it could take long time before it's confirmed.

In rare occasions I have seen my unconfirmed transaction drop.

I made a 1 sat/vbyte transaction, the network flooded with transactions (like 100sat/vbyte), and after a few weeks may valid transaction just disappeared.

I believe mempool nodes were full, as there is a 300mb limit for most mempool nodes.

I needed to make a new transaction (or rebroadcasted it, I don't remember exactly what I did)

But most times, you can't set low enough. 1 sat/vbyte transaction get confirmed somewhat fast most of times.
legendary
Activity: 2870
Merit: 7490
Crypto Swap Exchange
Even if it's possible, wouldn't such transaction have some vulnerability (especially when range between current and desired block height is very small)?
1. Pool owner could not include it until it's deemed invalid.
2. If you set very low fee (and didn't enable RBF) when mempool flooded with lots of transaction, it could take long time before it's confirmed.
legendary
Activity: 990
Merit: 1108
I want to make a bitcoin transaction, but if it does not make it into the blockchain before a certain blockheight, I want the transaction to expire so that it can no longer be inserted into the blockchain. Is this possible?

As a layer 2 developer of Bitcoin I deem this capability very important and useful.

No. Not only is that not possible, but such a feature is considered undesirable, as it destroys monotonicity.
Monotonicity is the property that once a tx in the mempool is verified, then it remains valid as long as
its inputs are not spent.

Monotonicity not only simplifies mempool management by a lot, but also provides reorg-safety.
This means that in case of a re-org, any undone transactions (that wasn't doublespent) can still be redone.
hero member
Activity: 813
Merit: 1944
Quote
Yeah but I don't want to double spend it, I want to stop it from being included in a block.
Double-spending is the only way I know that satisfies your conditions. If you don't want to include transaction X in a block, you have to include some kind of transaction Y. It can even move coins to the same address, but by including that and paying a fee, you simply invalidate any other transactions that could spend the same coins. You can even move the same amount of coins to the same address if you need that for some reason, but then you have to include some other input to pay your transaction fee.
legendary
Activity: 3472
Merit: 10611
I believe this is be possible using the lightning network and timelocks.

Take a look at this: Hashed Timelock Contracts (HTLCs)
That's not what it means. Essentially this means that the receiver can always spend the coins they receive in HTLC but the sender can spend those coins after a certain time passes (by that time the receiver forfeits those coins but not automatically).
The smart contracts I've seen are basically a conditional script where one statement has a locktime after which the sender can spend the same output. For example
Code:
Statement1:
  check (x seconds passed) check-sig
Statement2:
  check-sig

When it comes to locktimes, we can only set a date when the coins become spendable not the other way around.
legendary
Activity: 2352
Merit: 6089
bitcoindata.science
I want to make a bitcoin transaction, but if it does not make it into the blockchain before a certain blockheight, I want the transaction to expire so that it can no longer be inserted into the blockchain. Is this possible?


I believe this is be possible using the lightning network and timelocks.

Take a look at this: Hashed Timelock Contracts (HTLCs)

https://medium.com/hackernoon/what-are-hashed-timelock-contracts-htlcs-application-in-lightning-network-payment-channels-14437eeb9345
Bitcoin should implement this. Altough this would be a hard fork right?

You don't need to fork anything. You can do it in lightning. If not this specific solution (HTLCs), it might be possible to do something similar.
newbie
Activity: 24
Merit: 34
It can be only possible if you do it manually if the transaction is still unconfirmed on doing double spent to cancel the transaction but the expiration you talking about seems it's not possible.

Yeah but I don't want to double spend it, I want to stop it from being included in a block.
What I needed is that I can specify a block height in the transaction after which it would not be valid anymore for insertion in the chain.
Bitcoin should implement this. Altough this would be a hard fork right?
legendary
Activity: 3374
Merit: 3095
BTC price road to $80k
I don't think it's possible because if it's set to that certain date or blockheight it will trigger and will be broadcasted to the network I do not see if there is a way that time lock transaction can be expired or be canceled.

It can be only possible if you do it manually if the transaction is still unconfirmed on doing double spent to cancel the transaction but the expiration you talking about seems it's not possible.
newbie
Activity: 24
Merit: 34
I want to make a bitcoin transaction, but if it does not make it into the blockchain before a certain blockheight, I want the transaction to expire so that it can no longer be inserted into the blockchain. Is this possible?

As a layer 2 developer of Bitcoin I deem this capability very important and useful.
Jump to: