Transaction expiration #3509

pull cozz wants to merge 1 commits into bitcoin:master from cozz:master changing 18 files +270 −29
  1. cozz commented at 12:17 AM on January 11, 2014: contributor

    Motivation Transaction expiration is a fallback solution for never or too slow confirming transactions. Unconfirmed transactions expire after about 36 hours, if not included in a block by miners. The coins are credited back to the wallet and free to use again, just like sending the transaction had never happened. The transaction stays in the wallet, marked as expired. If someone would sync his wallet from scratch, the expired transaction would not appear anymore, because obviously it is not part of the blockchain.

    Implementation Abusing vin[0].nSequence for timestamping the transactions. Do not remove any of the original features of the field, even this pull #2340 would still be possible. People actually using the nLockTime features can decide, if they want to go with the timestamp, sending maximum of 1 tx per second, or start their sequences at, lets say, 2 billion. This would equal sending transactions "never expiring", just like it is now.

    Block version 3 Blocks version 3 do not allow expired transactions. Introduced same as block version 2 by a 95% majority softfork. Expired transactions are checked against blocktime, not local time, to avoid chain splits.

    Deployment Needs staging, but no hardfork. Older versions would not remove expired transactions from their mempool and consider follow-up transactions as double spend. So Step 1 would be introducing block version 3, the relay rule and the mempool removal. Then if block v3 and, lets say, 50% of all nodes have upgraded, transaction expiration can be introduced.

    Relay The relay rule is: do not relay transactions expiring in 24 hours or less

    Mining CreateNewBlock does not include transactions which would expire in 1 hour or less. This is a safety threshold because mining software may change the timestamp afterwards, resulting in mining an invalid block, containing expired transactions.

    Timeline 0 - CreateTransation 12hs later: stop relaying the transaction, other nodes would reject it, because it expires in 24 hours or less 35hs: 1 hour before expiring. CreateNewBlock does not include the tx anymore (reason see above). 36hs: transaction expires. nodes remove it from their mempool. 38hs: the wallet checks against block median time, not local time and adds another hour, to ensure the transaction is really expired and cannot appear in blocks anymore. So about ~2hs late, the wallet marks the tx as expired and frees the coins. Resulting in a total time of about 38 hours, from creating until expiring in the wallet.

    Faking It is allowed to fake your timestamp into the future, for whatever reasons. This can increase expiration time up to "never expiring". The relay rule is 24 hours, so you can fake your timestamp up to 12 hours into the past. This can reduce expiration time from 36 down to max 24 hours. If you fake more than 12 hours in the past, your transaction would not get relayed by other nodes anymore. If you fake more than 36 hours in the past, you would create an already expired transactions. This doesnt make sense anyway. This is not only about faking, but also misconfigured clocks up to 12 hours are no problem.

    System clock If transaction timestamping is on (default), the wallet refuses to create a transaction if your system clock is more than 12 hours behind the best block time. This is to ensure nobody creates an already expired transaction on accident.

    Off switch There is an option "bitcoin-qt -txtimestamp=0". If someone does this, transactions are not timestamped anymore. This equals sending "never expiring" transactions, just like it is now.

    Expiration times "Long" expiration times are good, because:

    • Merchants accepting 0-confirmations have at least 24 hours for every transaction to get confirmed, until it would expire. Allowing short expiration times could cause them troubles. Also such merchants should not only ask "Has the transaction been double spended", but also "Will it probably be confirmed". Transaction expiration makes this even more clear.
    • Transaction expiration is a fallback solution only. Not something that should be part of peoples usual workflow. Otherwise people would always start with a free transaction, and if it expires after an hour, try again, spamming the network. So allowing short expiration times would be an unnecessary waste of network resources. People sending a not confirming transaction have to wait about 38 hours, for the transaction to expire. Then they can decide, if they want to send the transaction again, maybe with a higher fee this time...

    Chainfork It is very unlikely, a transaction the wallet marked as expired suddenly appears in block. Basically only in chainfork scenarios possible. If this happens for whatever reasons, the transaction will be unmarked expired, and gets confirmed as normal. If then another longer chain would win again, the transaction could expire again. But even more unlikely scenario here. But still the wallet would handle these scenarios correctly.

    Screenshots Expired transaction: http://imageshack.com/a/img541/8103/h8j6.png

    Overviewpage shows [expired]: http://imageshack.com/a/img542/5076/be8y.png

    Description of unconfirmed transaction shows expires in x hours: http://imageshack.com/a/img856/8558/66ls.png

    RPC

    • listtransactions has a new filter attribut, showing expired transactions only: listtransactions "*" 10 0 "expired"
    • WalletTxToJSON shows a boolean expired true/false

    Notify -expirenotify=<cmd> can notify an external script when a wallet transaction expires

    Testing I have tested this locally, modifying the other necessary code parts, to test and debug the code part being tested. Tested all added code parts. I also tested the scenarios with expiring, then unexpiring again and what happens to the balances, unspent outputs etc. in these scenarios. Or what happens if transaction B depends on A, then A expires etc... Not tested payment request, but there shouldnt be any difference, I guess. No testplan or automated tests currently.

  2. Transaction expiration bdc2d515fa
  3. BitcoinPullTester commented at 12:56 AM on January 11, 2014: none

    Automatic sanity-testing: PASSED, see http://jenkins.bluematt.me/pull-tester/bdc2d515faf2b6459c0ee98de5cbc3149ff5970d for binaries and test log. This test script verifies pulls every time they are updated. It, however, dies sometimes and fails to test properly. If you are waiting on a test, please check timestamps to verify that the test.log is moving at http://jenkins.bluematt.me/pull-tester/current/ Contact BlueMatt on freenode if something looks broken.

  4. gmaxwell commented at 1:05 AM on January 11, 2014: contributor

    This makes reorganizations unsafe and makes coins less fungible, as a payment to you may have been made by a coin whos ancestors was recently expiring, and then an otherwise innocuous reorganization makes all its ancestors forever non-confirmable, even absent a double spend.

    Similar danger to reorgs/fungeability is why generated coin can't be spent for 100 blocks.

    I think advisory expiration would be greatly preferable, and then timed out transactions would just be double-spent before they are considered fully expired. This would avoid the reorg hazard, and also would avoid touching any consensus critical logic.

  5. cozz closed this on Jan 11, 2014

  6. DrahtBot locked this on Sep 8, 2021

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-21 18:16 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me