Skip to content

Instantly share code, notes, and snippets.

@harding
Created May 16, 2020 16:27
Show Gist options
  • Save harding/e1316f2e012a354decef939ca6cd82cc to your computer and use it in GitHub Desktop.
Save harding/e1316f2e012a354decef939ca6cd82cc to your computer and use it in GitHub Desktop.
[The proposal below is flawed because it doesn't work for presigned transactions that use BIP68,
such as those proposed for LN anchor outputs or for timelock vault proposals. It's probably
flawed in other ways too. I'm posting this in case it helps anyone else learn from my mistakes.]
On Sun, May 03, 2020 at 12:26:02AM +1000, Anthony Towns via bitcoin-dev wrote:
> [After updating the transaction digest to commit directly to
> scriptPubKey] we'd arguably still be missing:
>
> [...]
> what was the height of the coin? (Coin.nHeight)
>
> [...] committing to the height would make it hard to chain unconfirmed
> spends, so at least that part doesn't seem worth adding.
I think it might be nice for anti fee sniping purposes to commit to the
header hash at Coin.nHeight.[1] Any transaction that made such a
commitment would become invalid if any of its parent transactions were
reorged. Whereas existing nLockTime anti fee sniping still allows a
dishonest miner to include height-locked transactions in some blocks
(e.g. the new chaintip) and so the dishonest miner can still possibly
receive the transaction fee, a commitment to header hash is arguably
stronger because it would entirely prevent a transaction from being
included in a chain that reorged any of its parents.[2] However, header
hash commitments are also arguably weaker because they only matter when
a reorg is long enough that it affects a parent transaction. Happily,
both nLockTime and header hash commitments can be used simultaneously.
To allow chaining unconfirmed spends, this commitment could only be made
if any of the transaction's nSequence fields were set to a
BIP68-restricted value (i.e. consensus rules would require the
transaction's parent to be confirmed anyway).
A downside of such a commitment would be that a validation node would
need to maintain a fast map of heights to block header hashes, and such
a map would theoretically grow indefinitely, though only at about 1.6
MB/year.[3] Practically, the map wouldn't need entries for any blocks
without v1 segwit outputs.
Perhaps obviously, making it impossible for dishonest miners to reorg
some transactions also makes that impossible for honest miners, as in
the case of accidental reorgs. This violates the principle that "once a
transaction becomes valid, it should always remain valid" and preserving
that principle to a reasonable degree is the reason, for example, that
we continue to require coinbase transactions to mature or why we use
BIP65 CLTV and BIP112 CSV rather than just being able to push nHeight or
nSequence to the script stack. The full consequences of violating that
principle are beyond my ability to reason about at this moment (in
particular, I wonder how non-reorgable transactions would affect LN and
other contract protocols, especially those that require using BIP68
relative timelocks).
[1] This can also be used for replay protection during a hard fork,
although obviously the hard forkers can choose new consensus rules
that allow replays anyway. (See BIP115 or Johnson Lau's 2017
Scaling Bitcoin talk for more about using header hash commitments
for replay protection.)
[2] "Hello. My name is Inigo Montoya. You killed my father. Prepare to
die."
[3] 365 days * 144 blocks/day * 32 bytes/header hash (moderately less if the
terminal zero bytes used for PoW are trimmed)
-Dave
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment