> By redefining a bit of the nVersion field, eg the most significant bit, we 
> can apply coinbase-like txout handling to arbitrary transactions.
 
We already have that in OP_CHECKSEQUENCEVERIFY. You can have a system with no 
coinbase transactions at all, and use only OP_CHECKSEQUENCEVERIFY on the first 
transaction, and set sequence numbers to put a relative locktime of 100 blocks. 
Also, if you think some soft-fork is needed anyway, then I recommend building 
it around already existing OP_CHECKSEQUENCEVERIFY, than reinvent the wheel.
 
> Redefining an existing OP_Nop opcode, OP_Expire would terminate script 
> evaluation with an error
 
This one is also already there. We have reserved opcodes, like OP_RESERVED. You 
can do something like "<condition> OP_IF OP_RESERVED OP_ENDIF", and then, if 
"<condition>" is triggered in the Script, the whole transaction is marked as 
invalid. But if that condition is false, then everything is fine, and you can 
continue executing next opcodes. Again, the situation is the same as in 
previous case: build it around OP_RESERVED, that is just "OP_EXPIRE" with a 
different name than you want, and then the only thing you need, is soft-forking 
a proper condition on the stack.
 
On 2023-10-21 02:09:55 user Peter Todd via bitcoin-dev 
<bitcoin-...@lists.linuxfoundation.org> wrote:
On Mon, Oct 16, 2023 at 05:57:36PM +0100, Antoine Riard via bitcoin-dev wrote: 
> Here enter a replacement cycling attack. A malicious channel counterparty > 
can broadcast its HTLC-preimage transaction with a higher absolute fee and > 
higher feerate than the honest HTLC-timeout of the victim lightning node > and 
triggers a replacement. Both for legacy and anchor output channels, a > 
HTLC-preimage on a counterparty commitment transaction is malleable, i.e > 
additional inputs or outputs can be added. The HTLC-preimage spends an > 
unconfirmed and unrelated to the channel parent transaction M and conflicts > 
its child. The basic problem here is after the HTLC-timeout path becomes 
spendable, the HTLC-preimage path remains spendable. That's bad, because in 
this case we want spending the HTLC-preimage - if possible - to have an urgency 
attached to it to ensure that it happens before the previous HTLC-timeout is 
mined. So, why can't we make the HTLC-preimage path expire? Traditionally, 
we've tried to ensure that transactions - once valid - remain valid forever. We 
do this because we don't want transactions to become impossible to mine in the 
event of a large reorganization. A notable example of this design philosophy is 
seen in Bitcoin's rules around coinbase outputs: they only become spendable 
after 100 more blocks have been found; a 100 block reorg is quite unlikely. 
Enter the OP_Expire and the Coinbase Bit soft-fork upgrade. # Coinbase Bit By 
redefining a bit of the nVersion field, eg the most significant bit, we can 
apply coinbase-like txout handling to arbitrary transactions. Such a 
transaction's outputs would be treated similarly to a coinbase transaction, and 
would be spendable only after 100 more blocks had been mined. Due to this 
requirement, these transactions will pose no greater risk to reorg safety than 
the existing hazard of coinbase transactions themselves becoming invalid. Note 
how such a transaction is non-standard right now, ensuring compatibility with 
existing nodes in a soft-fork upgrade. # OP_Expire Redefining an existing 
OP_Nop opcode, OP_Expire would terminate script evaluation with an error if: 1) 
the Coinbase Bit was not set; or 2) the stack is empty; or 3) the top item on 
the stack was >= the block height of the containing block This is conceptually 
an AntiCheckLockTimeVerify: where CLTV _allows_ a txout to become spendable in 
a particular way in the future, Expire _prevents_ a txout from being spent in a 
particular way. Since OP_Expire requires the Coinbase Bit to be set, the reorg 
security of OP_Expire-using transactions is no worse than transactions spending 
miner coinbases. # How HTLC's Would Use OP_Expire Whenever revealing the 
preimage on-chain is necessary to the secure functioning of the HTLC-using 
protocol, we simply add an appropriate OP_Expire to the pre-image branch of the 
script along the lines of: If Expire Drop Hash EqualVerify CheckSig ElseIf # 
HTLC Expiration conditions ... EndIf Now the party receiving the pre-image has 
a deadline. Either they get a transaction spending the preimage mined, 
notifying the other party via the blockchain itself, or they fail to get the 
preimage mined in time, reverting control to the other party who can spend the 
HTLC output at their leisure, without strict time constraints. Since the 
HTLC-expired branch does *not* execute OP_Expire, the transaction spending the 
HTLC-expired branch does *not* need to set the Coinbase Bit. Thus it can be 
spent in a perfectly normal transaction, without restrictions. # Delta Encoding 
Expiration Rather than having a specific Coinbase Bit, it may also be feasible 
to encode the expiration height as a delta against a block-height nLockTime. In 
this variant, OP_Expire would work similarly to OP_CheckLockTimeVerify, by 
checking that the absolute expiration height was <= the requested expiration, 
allowing multiple HTLC preimage outputs to be spent in one transaction. If the 
top 16-bits were used, the maximum period a transaction could be valid would 
be: 2^16 blocks / 144 blocks/day = 455 days In this variant, a non-zero 
expiration delta would enable expiration behavior, as well as the coinbase-like 
output spending restriction. The remaining 16-bits of nVersion would remain 
available for other meanings. Similar to how CLTV and CSV verified nLockTime 
and nSequence respectively, verifying an expiration height encoded in the 
nVersion has the advantage of making an expiration height easy to detect 
without validating scripts. While Lightning's HTLC-success transactions 
currently use nLockTime=0, AFAIK there is no reason why they could not set 
nLockTime to be valid in the next block, allowing delta encoding to be used. ## 
Reusing Time-Based nLockTime Reusing time-based nLockTime's prior to some 
pre-2009 genesis point for expiration is another possibility (similar to how 
Lightning makes use of time-based nLockTime for signalling). However I believe 
this is not as desirable as delta encoding or a coinbase bit, as it would 
prevent transactions from using block nLockTime and expiration at the same 
time. It would also still require a coinbase bit or nVersion increase to ensure 
expiration-using transactions are non-standard. # Mempool Behavior Obviously, 
mempool logic will need to handle transactions that can expire differently than 
non-expiring transactions. One notable consideration is that nodes should 
require higher minimum relay fees for transactions close to their expiration 
height to ensure we don't waste bandwidth on transactions that have no 
potential to be mined. Considering the primary use-case, it is probably 
acceptable to always require a fee rate high enough to be mined in the next 
block. -- https://petertodd.org 'peter'[:-1]@petertodd.org 
_______________________________________________ bitcoin-dev mailing list 
bitcoin-...@lists.linuxfoundation.org 
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
_______________________________________________
Lightning-dev mailing list
Lightning-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev

Reply via email to