OP_BEFOREBLOCKVERIFY - discussing and opcode that invalidates a spend path after a certain block

OP_BEFOREBLOCKVERIFY - discussing and opcode that invalidates a spend path after a certain block
2021-06-10 18:35 ` Russell O'Connor
  
From: Billy Tetrud @ 2021-06-10 17:35 UTC (permalink / raw)
  To: Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 3092 bytes --]

Hi Everyone,

I'd like to open a discussion of an opcode I call OP_BEFOREBLOCKVERIFY
(OP_BBV) which is similar to ones that have been discussed before (eg
OP_BLOCKNUMBER). The opcode is very simple: the it takes as a parameter a
number representing a block height, and marks the transaction invalid if
the current block the transaction is being evaluated for is greater than or
equal to that block height, the transaction is invalid. I wrote up a bip
for OP_BBV here
<https://github.com/fresheneesz/bip-efficient-bitcoin-vaults/blob/main/bbv/bip-beforeblockverify.md>
.

The motivation for this opcode is primarily to do switch-off kinds of
transactions. Eg, an output that contains both a spend path that uses
OP_BBV and a spend path that uses OP_CHECKSEQUENCEVERIFY so that before a
particular block one person can spend, and after that block a different
person can spend. This can allow doing things like expiring payments or
reversible payments in a cheaper way. Currently, things like that require a
sequence of multiple transactions, however OP_BBV can do it in a single
transaction, making these applications a lot more economically feasible.

The particular application I'm most interested in is more efficient wallet
vaults. However, wallet vaults requires other new opcodes, and I've been
given the (good, I think) advice to start off this discussion with
something a bit more bite sized and manageable. So I want to keep this
discussion to OP_BBV and steer away from the specifics of the wallet vaults
I'm thinking of (which are more involved, requiring other new opcodes that
I think makes more sense to discuss in a different thread).

The main thing I'd like to discuss is the historical avoidance of and
stigma toward opcodes that can cause a valid transaction to become invalid.

It seems there are two concerns:

1. that an opcode like might create a DOS vector where a malicious actor
might be able to spam the mempool with transactions containing this opcode.
2. that an opcode like this could cause "bad" reorg behavior, where in a
reorg, transactions that were spent become not spend and not spendable
because they were mined too near their expiry point.

While I don't want to claim anything about opcodes that can cause spend
paths to expire in general, I do want to claim that *some* opcodes like
that are safe - in particular OP_BBV. In the context of OP_BBV
specifically, it seems to me like item 1 (mempool handling) is a solvable
problem and that point 2 (reorg issues) is not really a problem since
people should generally be waiting for 6 confirmations and software can
warn the user to wait for 6 confirmations in relevant scenarios where a
6-block reorg might reverse the transaction. I discuss this in detail in
the Design Tradeoffs and Risks
<https://github.com/fresheneesz/bip-efficient-bitcoin-vaults/blob/main/bbv/bip-beforeblockverify.md#transaction-expiry>
section
of the document I wrote for OP_BBV. I'd love to hear thoughts from others
on here about these things and especially the discussion of these issues in
the document I linked to.

Thanks,
BT

[-- Attachment #2: Type: text/html, Size: 3532 bytes --]

 permalink raw reply	[|nested]
2021-06-10 17:35 [bitcoin-dev] OP_BEFOREBLOCKVERIFY - discussing and opcode that invalidates a spend path after a certain block Billy Tetrud

  2021-06-10 22:19   ` Billy Tetrud
  
From: Russell O'Connor @ 2021-06-10 18:35 UTC (permalink / raw)
  To: Billy Tetrud, Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 3756 bytes --]

This is a continuation of the thread at
https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-April/018760.html
on this topic.

I still remain unconvinced that we ought to give up on the "reorg safety"
property that is explicitly part of Bitcoin's design.

On Thu, Jun 10, 2021 at 1:56 PM Billy Tetrud via bitcoin-dev <
bitcoin-dev@lists•linuxfoundation.org> wrote:

> Hi Everyone,
>
> I'd like to open a discussion of an opcode I call OP_BEFOREBLOCKVERIFY
> (OP_BBV) which is similar to ones that have been discussed before (eg
> OP_BLOCKNUMBER). The opcode is very simple: the it takes as a parameter a
> number representing a block height, and marks the transaction invalid if
> the current block the transaction is being evaluated for is greater than or
> equal to that block height, the transaction is invalid. I wrote up a bip
> for OP_BBV here
> <https://github.com/fresheneesz/bip-efficient-bitcoin-vaults/blob/main/bbv/bip-beforeblockverify.md>
> .
>
> The motivation for this opcode is primarily to do switch-off kinds of
> transactions. Eg, an output that contains both a spend path that uses
> OP_BBV and a spend path that uses OP_CHECKSEQUENCEVERIFY so that before a
> particular block one person can spend, and after that block a different
> person can spend. This can allow doing things like expiring payments or
> reversible payments in a cheaper way. Currently, things like that require a
> sequence of multiple transactions, however OP_BBV can do it in a single
> transaction, making these applications a lot more economically feasible.
>
> The particular application I'm most interested in is more efficient wallet
> vaults. However, wallet vaults requires other new opcodes, and I've been
> given the (good, I think) advice to start off this discussion with
> something a bit more bite sized and manageable. So I want to keep this
> discussion to OP_BBV and steer away from the specifics of the wallet vaults
> I'm thinking of (which are more involved, requiring other new opcodes that
> I think makes more sense to discuss in a different thread).
>
> The main thing I'd like to discuss is the historical avoidance of and
> stigma toward opcodes that can cause a valid transaction to become invalid.
>
> It seems there are two concerns:
>
> 1. that an opcode like might create a DOS vector where a malicious actor
> might be able to spam the mempool with transactions containing this opcode.
> 2. that an opcode like this could cause "bad" reorg behavior, where in a
> reorg, transactions that were spent become not spend and not spendable
> because they were mined too near their expiry point.
>
> While I don't want to claim anything about opcodes that can cause spend
> paths to expire in general, I do want to claim that *some* opcodes like
> that are safe - in particular OP_BBV. In the context of OP_BBV
> specifically, it seems to me like item 1 (mempool handling) is a solvable
> problem and that point 2 (reorg issues) is not really a problem since
> people should generally be waiting for 6 confirmations and software can
> warn the user to wait for 6 confirmations in relevant scenarios where a
> 6-block reorg might reverse the transaction. I discuss this in detail in
> the Design Tradeoffs and Risks
> <https://github.com/fresheneesz/bip-efficient-bitcoin-vaults/blob/main/bbv/bip-beforeblockverify.md#transaction-expiry> section
> of the document I wrote for OP_BBV. I'd love to hear thoughts from others
> on here about these things and especially the discussion of these issues in
> the document I linked to.
>
> Thanks,
> BT
>
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>

[-- Attachment #2: Type: text/html, Size: 4759 bytes --]

 permalink raw reply	[|nested]
2021-06-10 18:35 ` Russell O'Connor

  2021-06-10 23:20     ` Russell O'Connor
  
From: Billy Tetrud @ 2021-06-10 22:19 UTC (permalink / raw)
  To: Russell O'Connor;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 4289 bytes --]

@Russell In that thread, you quoted Satoshi there, but neither he nor you
really deeply explained the concern. Would you mind elaborating on a
situation that calls for concern here? Some deeper explanation of the
"reorg safety" property would also be helpful. I'd very much like to know
what your thoughts are on the specific points I brought up in the BIP as
well.

On Thu, Jun 10, 2021 at 11:35 AM Russell O'Connor <roconnor@blockstream•com>
wrote:

> This is a continuation of the thread at
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-April/018760.html
> on this topic.
>
> I still remain unconvinced that we ought to give up on the "reorg safety"
> property that is explicitly part of Bitcoin's design.
>
> On Thu, Jun 10, 2021 at 1:56 PM Billy Tetrud via bitcoin-dev <
> bitcoin-dev@lists•linuxfoundation.org> wrote:
>
>> Hi Everyone,
>>
>> I'd like to open a discussion of an opcode I call OP_BEFOREBLOCKVERIFY
>> (OP_BBV) which is similar to ones that have been discussed before (eg
>> OP_BLOCKNUMBER). The opcode is very simple: the it takes as a parameter
>> a number representing a block height, and marks the transaction invalid if
>> the current block the transaction is being evaluated for is greater than or
>> equal to that block height, the transaction is invalid. I wrote up a bip
>> for OP_BBV here
>> <https://github.com/fresheneesz/bip-efficient-bitcoin-vaults/blob/main/bbv/bip-beforeblockverify.md>
>> .
>>
>> The motivation for this opcode is primarily to do switch-off kinds of
>> transactions. Eg, an output that contains both a spend path that uses
>> OP_BBV and a spend path that uses OP_CHECKSEQUENCEVERIFY so that before a
>> particular block one person can spend, and after that block a different
>> person can spend. This can allow doing things like expiring payments or
>> reversible payments in a cheaper way. Currently, things like that require a
>> sequence of multiple transactions, however OP_BBV can do it in a single
>> transaction, making these applications a lot more economically feasible.
>>
>> The particular application I'm most interested in is more efficient
>> wallet vaults. However, wallet vaults requires other new opcodes, and I've
>> been given the (good, I think) advice to start off this discussion with
>> something a bit more bite sized and manageable. So I want to keep this
>> discussion to OP_BBV and steer away from the specifics of the wallet vaults
>> I'm thinking of (which are more involved, requiring other new opcodes that
>> I think makes more sense to discuss in a different thread).
>>
>> The main thing I'd like to discuss is the historical avoidance of and
>> stigma toward opcodes that can cause a valid transaction to become invalid.
>>
>> It seems there are two concerns:
>>
>> 1. that an opcode like might create a DOS vector where a malicious actor
>> might be able to spam the mempool with transactions containing this opcode.
>> 2. that an opcode like this could cause "bad" reorg behavior, where in a
>> reorg, transactions that were spent become not spend and not spendable
>> because they were mined too near their expiry point.
>>
>> While I don't want to claim anything about opcodes that can cause spend
>> paths to expire in general, I do want to claim that *some* opcodes like
>> that are safe - in particular OP_BBV. In the context of OP_BBV
>> specifically, it seems to me like item 1 (mempool handling) is a solvable
>> problem and that point 2 (reorg issues) is not really a problem since
>> people should generally be waiting for 6 confirmations and software can
>> warn the user to wait for 6 confirmations in relevant scenarios where a
>> 6-block reorg might reverse the transaction. I discuss this in detail in
>> the Design Tradeoffs and Risks
>> <https://github.com/fresheneesz/bip-efficient-bitcoin-vaults/blob/main/bbv/bip-beforeblockverify.md#transaction-expiry> section
>> of the document I wrote for OP_BBV. I'd love to hear thoughts from others
>> on here about these things and especially the discussion of these issues in
>> the document I linked to.
>>
>> Thanks,
>> BT
>>
>> _______________________________________________
>> bitcoin-dev mailing list
>> bitcoin-dev@lists•linuxfoundation.org
>> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>>
>

[-- Attachment #2: Type: text/html, Size: 5552 bytes --]

 permalink raw reply	[|nested]
2021-06-10 22:19   ` Billy Tetrud

  2021-06-11  5:59       ` Billy Tetrud
  
From: Russell O'Connor @ 2021-06-10 23:20 UTC (permalink / raw)
  To: Billy Tetrud;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 6592 bytes --]

As it stands today, in order to double spend a transaction during a reorg,
one must take an active role of recognizing that a reorg has happened, hope
that the new branch has completely omitted your spending transaction, and
then quickly broadcast a replacement transaction with a higher fee to
outbid your previous transaction.

However with, pretty much any change to Bitcoin that leads to non-monotonic
validity rules, that is any rule where transactions that are valid at one
tip, can become invalid at a latter tip through some other means than their
inputs being spent, such as OP_BBV, one can design a wallet to passively
take advantage of reorgs by always spending through an OP_BBV that is on
the verge of becoming invalid.  Then you just have to sit back and wait for
a suitable reorg to take back your UTXO for you without any work.  I would
probably attempt to build such a wallet for myself should any OP_BBV-like
proposal be implemented.  Think of it as an auto-double spend wallet.

Some people hold the opinion that there is no meaningful distinction
between the active and passive roles in these two scenarios.  I'm not
convinced.  I see a material difference between needing to actively
broadcast a replacement transaction and passively waiting for your
transaction to fall out of validity.  I also see a material difference
between needing the transaction to be completely omitted from the reorging
chain versus just having the transaction fail a height qualification in the
reorging chain.

(There are a few other lesser problems with an OP_BBV proposal, including
the fact that Bitcoin software tends to cache script validity so you'd want
to use the taproot annex instead of pure script; and a possible issue that
the proposal defeats limits on transaction replacement because now instead
of meeting minimum thresholds for fee bumping you can just let the previous
transaction expire and bump the fee by a fraction (though you are
effectively rate limited so maybe that is considered sufficiently
mitigated?).  But there is little point in addressing these lesser concerns
if the main concern is outstanding.)

On Thu, Jun 10, 2021 at 6:20 PM Billy Tetrud <billy.tetrud@gmail•com> wrote:

> @Russell In that thread, you quoted Satoshi there, but neither he nor you
> really deeply explained the concern. Would you mind elaborating on a
> situation that calls for concern here? Some deeper explanation of the
> "reorg safety" property would also be helpful. I'd very much like to know
> what your thoughts are on the specific points I brought up in the BIP as
> well.
>
> On Thu, Jun 10, 2021 at 11:35 AM Russell O'Connor <
> roconnor@blockstream•com> wrote:
>
>> This is a continuation of the thread at
>> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-April/018760.html
>> on this topic.
>>
>> I still remain unconvinced that we ought to give up on the "reorg safety"
>> property that is explicitly part of Bitcoin's design.
>>
>> On Thu, Jun 10, 2021 at 1:56 PM Billy Tetrud via bitcoin-dev <
>> bitcoin-dev@lists•linuxfoundation.org> wrote:
>>
>>> Hi Everyone,
>>>
>>> I'd like to open a discussion of an opcode I call OP_BEFOREBLOCKVERIFY
>>> (OP_BBV) which is similar to ones that have been discussed before (eg
>>> OP_BLOCKNUMBER). The opcode is very simple: the it takes as a parameter
>>> a number representing a block height, and marks the transaction invalid if
>>> the current block the transaction is being evaluated for is greater than or
>>> equal to that block height, the transaction is invalid. I wrote up a bip
>>> for OP_BBV here
>>> <https://github.com/fresheneesz/bip-efficient-bitcoin-vaults/blob/main/bbv/bip-beforeblockverify.md>
>>> .
>>>
>>> The motivation for this opcode is primarily to do switch-off kinds of
>>> transactions. Eg, an output that contains both a spend path that uses
>>> OP_BBV and a spend path that uses OP_CHECKSEQUENCEVERIFY so that before a
>>> particular block one person can spend, and after that block a different
>>> person can spend. This can allow doing things like expiring payments or
>>> reversible payments in a cheaper way. Currently, things like that require a
>>> sequence of multiple transactions, however OP_BBV can do it in a single
>>> transaction, making these applications a lot more economically feasible.
>>>
>>> The particular application I'm most interested in is more efficient
>>> wallet vaults. However, wallet vaults requires other new opcodes, and I've
>>> been given the (good, I think) advice to start off this discussion with
>>> something a bit more bite sized and manageable. So I want to keep this
>>> discussion to OP_BBV and steer away from the specifics of the wallet vaults
>>> I'm thinking of (which are more involved, requiring other new opcodes that
>>> I think makes more sense to discuss in a different thread).
>>>
>>> The main thing I'd like to discuss is the historical avoidance of and
>>> stigma toward opcodes that can cause a valid transaction to become invalid.
>>>
>>> It seems there are two concerns:
>>>
>>> 1. that an opcode like might create a DOS vector where a malicious actor
>>> might be able to spam the mempool with transactions containing this opcode.
>>> 2. that an opcode like this could cause "bad" reorg behavior, where in a
>>> reorg, transactions that were spent become not spend and not spendable
>>> because they were mined too near their expiry point.
>>>
>>> While I don't want to claim anything about opcodes that can cause spend
>>> paths to expire in general, I do want to claim that *some* opcodes like
>>> that are safe - in particular OP_BBV. In the context of OP_BBV
>>> specifically, it seems to me like item 1 (mempool handling) is a solvable
>>> problem and that point 2 (reorg issues) is not really a problem since
>>> people should generally be waiting for 6 confirmations and software can
>>> warn the user to wait for 6 confirmations in relevant scenarios where a
>>> 6-block reorg might reverse the transaction. I discuss this in detail in
>>> the Design Tradeoffs and Risks
>>> <https://github.com/fresheneesz/bip-efficient-bitcoin-vaults/blob/main/bbv/bip-beforeblockverify.md#transaction-expiry> section
>>> of the document I wrote for OP_BBV. I'd love to hear thoughts from others
>>> on here about these things and especially the discussion of these issues in
>>> the document I linked to.
>>>
>>> Thanks,
>>> BT
>>>
>>> _______________________________________________
>>> bitcoin-dev mailing list
>>> bitcoin-dev@lists•linuxfoundation.org
>>> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>>>
>>

[-- Attachment #2: Type: text/html, Size: 8167 bytes --]

 permalink raw reply	[|nested]
2021-06-10 23:20     ` Russell O'Connor

  2021-06-11 11:12         ` James MacWhyte
  
From: Billy Tetrud @ 2021-06-11  5:59 UTC (permalink / raw)
  To: Russell O'Connor;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 10006 bytes --]

>  one can design a wallet to passively take advantage of reorgs

It does sound like this is the central issue. I can certainly see that it's
materially different than current double spending ability. Double spending
via reorgs today requires either active participation and above-average
connection to miners or luck.

The easiest method of double spending I can think of is the following.
Consider if a user broadcasts an RBF transaction as soon as the original
transaction is mined. I assume the transaction won't propagate through the
network because any node that has received the newest block will see it as
an invalid transaction, is that right? Is there no significant possibility
that enough of the network hasn't seen the block yet to transmit the RBF
transaction widely enough to get incorporated into a reorg? This would
certainly be something wallets could do automatically. It certainly does
seem like at very least this would have a much lower success rate than your
auto-double-spend wallet.

In any case, what if we apply the same logic to non-monotonic transactions?
What if we program nodes to reject such transactions that are too close to
the borderline? For example, if nodes rejected transactions that could
expire within 100 blocks, it would be much less likely for this kind of
thing to be done at point of sale, and there would be a much higher chance
that whatever recipient that's willing to wait 100 blocks would be willing
to wait 6 blocks more to be sure no reorg happens. It would also be a lot
more likely that the transaction is confirmed well before it might expire.
Not a perfect solution, to be sure. But it could substantially limit the
cases and likelihoods that passive double-spend attempts would succeed. But
miners could still get and include transactions in blocks regardless of
this, and they have an incentive to (to maximize the fees they collect). It
at least seems plausible that those incentives would undermine this
solution.

But it seems like all this is only a problem for people who are considering
1 confirmation to be effectively finalized. Users and programmatic systems
alike simply wait for some condition to be true to recognize payment as
having completed. Systems could simply be programmed so the condition is at
least 6 confirmations for any non-monotonic transaction, or all
transactions. 6 confirmations is the accepted standard of finalization,
isn't it? Users looking at their software should be able to see that a
confirmation has happened but that this isn't enough to be considered
finalized. As long as this is standard, no problem should really exist,
right? Except within incorrectly written software or people taking it upon
themselves to define finalization on their own. People who accept 0-conf
transactions are similarly using a non-standard definition of finalization
and are putting themselves at even greater risk for double spends. How
would this be any different?

>  there is little point in addressing these lesser concerns if the main
concern is outstanding

I agree, it makes the most sense to discuss the above points rather than
getting into the weeds about more minor issues.

On Thu, Jun 10, 2021 at 4:20 PM Russell O'Connor <roconnor@blockstream•com>
wrote:

> As it stands today, in order to double spend a transaction during a reorg,
> one must take an active role of recognizing that a reorg has happened, hope
> that the new branch has completely omitted your spending transaction, and
> then quickly broadcast a replacement transaction with a higher fee to
> outbid your previous transaction.
>
> However with, pretty much any change to Bitcoin that leads to
> non-monotonic validity rules, that is any rule where transactions that are
> valid at one tip, can become invalid at a latter tip through some other
> means than their inputs being spent, such as OP_BBV, one can design a
> wallet to passively take advantage of reorgs by always spending through an
> OP_BBV that is on the verge of becoming invalid.  Then you just have to sit
> back and wait for a suitable reorg to take back your UTXO for you without
> any work.  I would probably attempt to build such a wallet for myself
> should any OP_BBV-like proposal be implemented.  Think of it as an
> auto-double spend wallet.
>
> Some people hold the opinion that there is no meaningful distinction
> between the active and passive roles in these two scenarios.  I'm not
> convinced.  I see a material difference between needing to actively
> broadcast a replacement transaction and passively waiting for your
> transaction to fall out of validity.  I also see a material difference
> between needing the transaction to be completely omitted from the reorging
> chain versus just having the transaction fail a height qualification in the
> reorging chain.
>
> (There are a few other lesser problems with an OP_BBV proposal, including
> the fact that Bitcoin software tends to cache script validity so you'd want
> to use the taproot annex instead of pure script; and a possible issue that
> the proposal defeats limits on transaction replacement because now instead
> of meeting minimum thresholds for fee bumping you can just let the previous
> transaction expire and bump the fee by a fraction (though you are
> effectively rate limited so maybe that is considered sufficiently
> mitigated?).  But there is little point in addressing these lesser concerns
> if the main concern is outstanding.)
>
> On Thu, Jun 10, 2021 at 6:20 PM Billy Tetrud <billy.tetrud@gmail•com>
> wrote:
>
>> @Russell In that thread, you quoted Satoshi there, but neither he nor you
>> really deeply explained the concern. Would you mind elaborating on a
>> situation that calls for concern here? Some deeper explanation of the
>> "reorg safety" property would also be helpful. I'd very much like to know
>> what your thoughts are on the specific points I brought up in the BIP as
>> well.
>>
>> On Thu, Jun 10, 2021 at 11:35 AM Russell O'Connor <
>> roconnor@blockstream•com> wrote:
>>
>>> This is a continuation of the thread at
>>> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-April/018760.html
>>> on this topic.
>>>
>>> I still remain unconvinced that we ought to give up on the "reorg
>>> safety" property that is explicitly part of Bitcoin's design.
>>>
>>> On Thu, Jun 10, 2021 at 1:56 PM Billy Tetrud via bitcoin-dev <
>>> bitcoin-dev@lists•linuxfoundation.org> wrote:
>>>
>>>> Hi Everyone,
>>>>
>>>> I'd like to open a discussion of an opcode I call OP_BEFOREBLOCKVERIFY
>>>> (OP_BBV) which is similar to ones that have been discussed before (eg
>>>> OP_BLOCKNUMBER). The opcode is very simple: the it takes as a
>>>> parameter a number representing a block height, and marks the transaction
>>>> invalid if the current block the transaction is being evaluated for is
>>>> greater than or equal to that block height, the transaction is invalid. I
>>>> wrote up a bip for OP_BBV here
>>>> <https://github.com/fresheneesz/bip-efficient-bitcoin-vaults/blob/main/bbv/bip-beforeblockverify.md>
>>>> .
>>>>
>>>> The motivation for this opcode is primarily to do switch-off kinds of
>>>> transactions. Eg, an output that contains both a spend path that uses
>>>> OP_BBV and a spend path that uses OP_CHECKSEQUENCEVERIFY so that before a
>>>> particular block one person can spend, and after that block a different
>>>> person can spend. This can allow doing things like expiring payments or
>>>> reversible payments in a cheaper way. Currently, things like that require a
>>>> sequence of multiple transactions, however OP_BBV can do it in a single
>>>> transaction, making these applications a lot more economically feasible.
>>>>
>>>> The particular application I'm most interested in is more efficient
>>>> wallet vaults. However, wallet vaults requires other new opcodes, and I've
>>>> been given the (good, I think) advice to start off this discussion with
>>>> something a bit more bite sized and manageable. So I want to keep this
>>>> discussion to OP_BBV and steer away from the specifics of the wallet vaults
>>>> I'm thinking of (which are more involved, requiring other new opcodes that
>>>> I think makes more sense to discuss in a different thread).
>>>>
>>>> The main thing I'd like to discuss is the historical avoidance of and
>>>> stigma toward opcodes that can cause a valid transaction to become invalid.
>>>>
>>>> It seems there are two concerns:
>>>>
>>>> 1. that an opcode like might create a DOS vector where a malicious
>>>> actor might be able to spam the mempool with transactions containing this
>>>> opcode.
>>>> 2. that an opcode like this could cause "bad" reorg behavior, where in
>>>> a reorg, transactions that were spent become not spend and not spendable
>>>> because they were mined too near their expiry point.
>>>>
>>>> While I don't want to claim anything about opcodes that can cause spend
>>>> paths to expire in general, I do want to claim that *some* opcodes like
>>>> that are safe - in particular OP_BBV. In the context of OP_BBV
>>>> specifically, it seems to me like item 1 (mempool handling) is a solvable
>>>> problem and that point 2 (reorg issues) is not really a problem since
>>>> people should generally be waiting for 6 confirmations and software can
>>>> warn the user to wait for 6 confirmations in relevant scenarios where a
>>>> 6-block reorg might reverse the transaction. I discuss this in detail in
>>>> the Design Tradeoffs and Risks
>>>> <https://github.com/fresheneesz/bip-efficient-bitcoin-vaults/blob/main/bbv/bip-beforeblockverify.md#transaction-expiry> section
>>>> of the document I wrote for OP_BBV. I'd love to hear thoughts from others
>>>> on here about these things and especially the discussion of these issues in
>>>> the document I linked to.
>>>>
>>>> Thanks,
>>>> BT
>>>>
>>>> _______________________________________________
>>>> bitcoin-dev mailing list
>>>> bitcoin-dev@lists•linuxfoundation.org
>>>> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>>>>
>>>

[-- Attachment #2: Type: text/html, Size: 11929 bytes --]

 permalink raw reply	[|nested]
2021-06-11  5:59       ` Billy Tetrud

  2021-06-11 11:43           ` Russell O'Connor
  
From: James MacWhyte @ 2021-06-11 11:12 UTC (permalink / raw)
  To: Billy Tetrud, Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 12310 bytes --]

@Billy I like the idea. It is very obvious how useful an opcode like this
would be! (My background is in wallet implementation)

@Russell I do understand your concerns of monotonism, however I'm having a
hard time really coming up with an attack vector. You said "one can design
a wallet to passively take advantage of reorgs by always spending through
an OP_BBV that is on the verge of becoming invalid." Unless I'm mistaken,
this means you would need to send yourself a fresh transaction using OP_BBV
set to, say, 2 blocks in the future, then immediately spend that output in
a new payment to someone else and hope a reorg happens. Does this mean the
theoretical double-spend wallet you are proposing would have to send two
transactions every time you make a single payment, doubling the transaction
fees and adding more uncertainty around when the second transaction would
get confirmed?

In a normal double spend scenario, there is no cost to a failed attempt,
but much to gain from a success. With your design, there is a real cost to
every single attempt (transaction fees) and no evidence that the rate of
success would be higher (you still have to bet on the reorg not including
your transaction in the first few blocks). It sounds like this new system
would actually be less attractive to double spenders than the current model!

I also agree with Billy's idea for relay rules. We already have abusable
chain rules (e.g. a tx can be included in a block with 0 transaction fee
[spam?]) but we add protection with relay rules (e.g. minimum fee to
relay). I don't see how this would be any different, if the chain rules
only enforced the block height for confirmation and the relay rules forced
a minimum OP_BBV value in order to protect against reorg double spends.

James


On Fri, Jun 11, 2021 at 11:00 AM Billy Tetrud via bitcoin-dev <
bitcoin-dev@lists•linuxfoundation.org> wrote:

> >  one can design a wallet to passively take advantage of reorgs
>
> It does sound like this is the central issue. I can certainly see that
> it's materially different than current double spending ability. Double
> spending via reorgs today requires either active participation and
> above-average connection to miners or luck.
>
> The easiest method of double spending I can think of is the following.
> Consider if a user broadcasts an RBF transaction as soon as the original
> transaction is mined. I assume the transaction won't propagate through the
> network because any node that has received the newest block will see it as
> an invalid transaction, is that right? Is there no significant possibility
> that enough of the network hasn't seen the block yet to transmit the RBF
> transaction widely enough to get incorporated into a reorg? This would
> certainly be something wallets could do automatically. It certainly does
> seem like at very least this would have a much lower success rate than your
> auto-double-spend wallet.
>
> In any case, what if we apply the same logic to non-monotonic
> transactions? What if we program nodes to reject such transactions that are
> too close to the borderline? For example, if nodes rejected transactions
> that could expire within 100 blocks, it would be much less likely for this
> kind of thing to be done at point of sale, and there would be a much higher
> chance that whatever recipient that's willing to wait 100 blocks would be
> willing to wait 6 blocks more to be sure no reorg happens. It would also be
> a lot more likely that the transaction is confirmed well before it might
> expire. Not a perfect solution, to be sure. But it could substantially
> limit the cases and likelihoods that passive double-spend attempts would
> succeed. But miners could still get and include transactions in blocks
> regardless of this, and they have an incentive to (to maximize the fees
> they collect). It at least seems plausible that those incentives would
> undermine this solution.
>
> But it seems like all this is only a problem for people who are
> considering 1 confirmation to be effectively finalized. Users and
> programmatic systems alike simply wait for some condition to be true to
> recognize payment as having completed. Systems could simply be programmed
> so the condition is at least 6 confirmations for any non-monotonic
> transaction, or all transactions. 6 confirmations is the accepted standard
> of finalization, isn't it? Users looking at their software should be able
> to see that a confirmation has happened but that this isn't enough to be
> considered finalized. As long as this is standard, no problem should really
> exist, right? Except within incorrectly written software or people taking
> it upon themselves to define finalization on their own. People who accept
> 0-conf transactions are similarly using a non-standard definition of
> finalization and are putting themselves at even greater risk for double
> spends. How would this be any different?
>
> >  there is little point in addressing these lesser concerns if the main
> concern is outstanding
>
> I agree, it makes the most sense to discuss the above points rather than
> getting into the weeds about more minor issues.
>
> On Thu, Jun 10, 2021 at 4:20 PM Russell O'Connor <roconnor@blockstream•com>
> wrote:
>
>> As it stands today, in order to double spend a transaction during a
>> reorg, one must take an active role of recognizing that a reorg has
>> happened, hope that the new branch has completely omitted your spending
>> transaction, and then quickly broadcast a replacement transaction with a
>> higher fee to outbid your previous transaction.
>>
>> However with, pretty much any change to Bitcoin that leads to
>> non-monotonic validity rules, that is any rule where transactions that are
>> valid at one tip, can become invalid at a latter tip through some other
>> means than their inputs being spent, such as OP_BBV, one can design a
>> wallet to passively take advantage of reorgs by always spending through an
>> OP_BBV that is on the verge of becoming invalid.  Then you just have to sit
>> back and wait for a suitable reorg to take back your UTXO for you without
>> any work.  I would probably attempt to build such a wallet for myself
>> should any OP_BBV-like proposal be implemented.  Think of it as an
>> auto-double spend wallet.
>>
>> Some people hold the opinion that there is no meaningful distinction
>> between the active and passive roles in these two scenarios.  I'm not
>> convinced.  I see a material difference between needing to actively
>> broadcast a replacement transaction and passively waiting for your
>> transaction to fall out of validity.  I also see a material difference
>> between needing the transaction to be completely omitted from the reorging
>> chain versus just having the transaction fail a height qualification in the
>> reorging chain.
>>
>> (There are a few other lesser problems with an OP_BBV proposal, including
>> the fact that Bitcoin software tends to cache script validity so you'd want
>> to use the taproot annex instead of pure script; and a possible issue that
>> the proposal defeats limits on transaction replacement because now instead
>> of meeting minimum thresholds for fee bumping you can just let the previous
>> transaction expire and bump the fee by a fraction (though you are
>> effectively rate limited so maybe that is considered sufficiently
>> mitigated?).  But there is little point in addressing these lesser concerns
>> if the main concern is outstanding.)
>>
>> On Thu, Jun 10, 2021 at 6:20 PM Billy Tetrud <billy.tetrud@gmail•com>
>> wrote:
>>
>>> @Russell In that thread, you quoted Satoshi there, but neither he nor
>>> you really deeply explained the concern. Would you mind elaborating on a
>>> situation that calls for concern here? Some deeper explanation of the
>>> "reorg safety" property would also be helpful. I'd very much like to know
>>> what your thoughts are on the specific points I brought up in the BIP as
>>> well.
>>>
>>> On Thu, Jun 10, 2021 at 11:35 AM Russell O'Connor <
>>> roconnor@blockstream•com> wrote:
>>>
>>>> This is a continuation of the thread at
>>>> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-April/018760.html
>>>> on this topic.
>>>>
>>>> I still remain unconvinced that we ought to give up on the "reorg
>>>> safety" property that is explicitly part of Bitcoin's design.
>>>>
>>>> On Thu, Jun 10, 2021 at 1:56 PM Billy Tetrud via bitcoin-dev <
>>>> bitcoin-dev@lists•linuxfoundation.org> wrote:
>>>>
>>>>> Hi Everyone,
>>>>>
>>>>> I'd like to open a discussion of an opcode I call OP_BEFOREBLOCKVERIFY
>>>>> (OP_BBV) which is similar to ones that have been discussed before (eg
>>>>> OP_BLOCKNUMBER). The opcode is very simple: the it takes as a
>>>>> parameter a number representing a block height, and marks the transaction
>>>>> invalid if the current block the transaction is being evaluated for is
>>>>> greater than or equal to that block height, the transaction is invalid. I
>>>>> wrote up a bip for OP_BBV here
>>>>> <https://github.com/fresheneesz/bip-efficient-bitcoin-vaults/blob/main/bbv/bip-beforeblockverify.md>
>>>>> .
>>>>>
>>>>> The motivation for this opcode is primarily to do switch-off kinds of
>>>>> transactions. Eg, an output that contains both a spend path that uses
>>>>> OP_BBV and a spend path that uses OP_CHECKSEQUENCEVERIFY so that before a
>>>>> particular block one person can spend, and after that block a different
>>>>> person can spend. This can allow doing things like expiring payments or
>>>>> reversible payments in a cheaper way. Currently, things like that require a
>>>>> sequence of multiple transactions, however OP_BBV can do it in a single
>>>>> transaction, making these applications a lot more economically feasible.
>>>>>
>>>>> The particular application I'm most interested in is more efficient
>>>>> wallet vaults. However, wallet vaults requires other new opcodes, and I've
>>>>> been given the (good, I think) advice to start off this discussion with
>>>>> something a bit more bite sized and manageable. So I want to keep this
>>>>> discussion to OP_BBV and steer away from the specifics of the wallet vaults
>>>>> I'm thinking of (which are more involved, requiring other new opcodes that
>>>>> I think makes more sense to discuss in a different thread).
>>>>>
>>>>> The main thing I'd like to discuss is the historical avoidance of and
>>>>> stigma toward opcodes that can cause a valid transaction to become invalid.
>>>>>
>>>>> It seems there are two concerns:
>>>>>
>>>>> 1. that an opcode like might create a DOS vector where a malicious
>>>>> actor might be able to spam the mempool with transactions containing this
>>>>> opcode.
>>>>> 2. that an opcode like this could cause "bad" reorg behavior, where in
>>>>> a reorg, transactions that were spent become not spend and not spendable
>>>>> because they were mined too near their expiry point.
>>>>>
>>>>> While I don't want to claim anything about opcodes that can cause
>>>>> spend paths to expire in general, I do want to claim that *some* opcodes
>>>>> like that are safe - in particular OP_BBV. In the context of OP_BBV
>>>>> specifically, it seems to me like item 1 (mempool handling) is a solvable
>>>>> problem and that point 2 (reorg issues) is not really a problem since
>>>>> people should generally be waiting for 6 confirmations and software can
>>>>> warn the user to wait for 6 confirmations in relevant scenarios where a
>>>>> 6-block reorg might reverse the transaction. I discuss this in detail in
>>>>> the Design Tradeoffs and Risks
>>>>> <https://github.com/fresheneesz/bip-efficient-bitcoin-vaults/blob/main/bbv/bip-beforeblockverify.md#transaction-expiry> section
>>>>> of the document I wrote for OP_BBV. I'd love to hear thoughts from others
>>>>> on here about these things and especially the discussion of these issues in
>>>>> the document I linked to.
>>>>>
>>>>> Thanks,
>>>>> BT
>>>>>
>>>>> _______________________________________________
>>>>> bitcoin-dev mailing list
>>>>> bitcoin-dev@lists•linuxfoundation.org
>>>>> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>>>>>
>>>> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>

[-- Attachment #2: Type: text/html, Size: 14772 bytes --]

 permalink raw reply	[|nested]
2021-06-11 11:12         ` James MacWhyte

  2021-06-12  7:59             ` Billy Tetrud
  
From: Russell O'Connor @ 2021-06-11 11:43 UTC (permalink / raw)
  To: James MacWhyte;  Bitcoin Protocol Discussion, Billy Tetrud

[-- Attachment #1: Type: text/plain, Size: 2912 bytes --]

On Fri, Jun 11, 2021 at 7:12 AM James MacWhyte <macwhyte@gmail•com> wrote:

> @Billy I like the idea. It is very obvious how useful an opcode like this
> would be! (My background is in wallet implementation)
>
> @Russell I do understand your concerns of monotonism, however I'm having a
> hard time really coming up with an attack vector. You said "one can design
> a wallet to passively take advantage of reorgs by always spending through
> an OP_BBV that is on the verge of becoming invalid." Unless I'm mistaken,
> this means you would need to send yourself a fresh transaction using OP_BBV
> set to, say, 2 blocks in the future, then immediately spend that output in
> a new payment to someone else and hope a reorg happens. Does this mean the
> theoretical double-spend wallet you are proposing would have to send two
> transactions every time you make a single payment, doubling the transaction
> fees and adding more uncertainty around when the second transaction would
> get confirmed?
>

Assuming the proposal is rewritten to place the maxheight into the taproot
annex in order to address the issue with caching of script validity, then
this auto-double-spend wallet would send every payment with an annex value
that limits the payment to being valid only up to the next block.  If the
payment doesn't make it into the next block, then resign it with the annex
incremented to the next block, and repeat.


> In a normal double spend scenario, there is no cost to a failed attempt,
> but much to gain from a success. With your design, there is a real cost to
> every single attempt (transaction fees) and no evidence that the rate of
> success would be higher (you still have to bet on the reorg not including
> your transaction in the first few blocks). It sounds like this new system
> would actually be less attractive to double spenders than the current model!
>
> I also agree with Billy's idea for relay rules. We already have abusable
> chain rules (e.g. a tx can be included in a block with 0 transaction fee
> [spam?]) but we add protection with relay rules (e.g. minimum fee to
> relay). I don't see how this would be any different, if the chain rules
> only enforced the block height for confirmation and the relay rules forced
> a minimum OP_BBV value in order to protect against reorg double spends.
>

The inclusion of a tx with 0 transaction fee in a block is not in of itself
an abuse.  There is nothing wrong with blocks containing such
transactions.  The *relay* of 0 transaction fee transactions is what is an
abuse because it allows one to usurp Bitcoin's gossip network for their own
arbitrary communications platform without cost.  Most Bitcoin users aren't
signing up for being a usenet provider.  So, by policy, nodes require a
cost to relay transactions so that broadcasting isn't free. Even when that
price is paid to someone else, it still is an effective limitation on abuse.

[-- Attachment #2: Type: text/html, Size: 3513 bytes --]

 permalink raw reply	[|nested]
2021-06-11 11:43           ` Russell O'Connor

  2021-06-12 15:58               ` Russell O'Connor
  
From: Billy Tetrud @ 2021-06-12  7:59 UTC (permalink / raw)
  To: Russell O'Connor, Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 4647 bytes --]

>  taproot annex

From what I can tell, the annex is basically additional inputs to a script
that might have additional constraints put on it. Is that right? I don't
quite follow how moving the max height to the annex helps script caching
here. I wasn't able to find much information on how the annex is envisioned
to be used. Would you mind elaborating on how this would work?

Also, I think the proposal as it stands already addresses script caching
(in the Transaction Evaluation section
<https://github.com/fresheneesz/bip-efficient-bitcoin-vaults/blob/main/bbv/bip-beforeblockverify.md#transaction-evaluation>).
The result of the script can be cached as long as the cache item also
contains information requiring just the OP_BBV to be re-evaluated (for the
relevant block).

> this auto-double-spend wallet would send every payment with an annex value
that limits the payment to being valid only up to the next block

One possible solution to that would be to require that the input to OP_BBV
to be in the script itself and not originate from the witness.

Regardless, I think the ideal solution is to not have any of these such
rules if we can simply change the definition for what counts as
finalization to account for the fact that BBV transactions mined close to
their expiration. Is there a reason this finalization-redefinition is not
an adequate solution?

On Fri, Jun 11, 2021 at 4:44 AM Russell O'Connor via bitcoin-dev <
bitcoin-dev@lists•linuxfoundation.org> wrote:

>
>
> On Fri, Jun 11, 2021 at 7:12 AM James MacWhyte <macwhyte@gmail•com> wrote:
>
>> @Billy I like the idea. It is very obvious how useful an opcode like this
>> would be! (My background is in wallet implementation)
>>
>> @Russell I do understand your concerns of monotonism, however I'm having
>> a hard time really coming up with an attack vector. You said "one can
>> design a wallet to passively take advantage of reorgs by always spending
>> through an OP_BBV that is on the verge of becoming invalid." Unless I'm
>> mistaken, this means you would need to send yourself a fresh transaction
>> using OP_BBV set to, say, 2 blocks in the future, then immediately spend
>> that output in a new payment to someone else and hope a reorg happens. Does
>> this mean the theoretical double-spend wallet you are proposing would have
>> to send two transactions every time you make a single payment, doubling the
>> transaction fees and adding more uncertainty around when the second
>> transaction would get confirmed?
>>
>
> Assuming the proposal is rewritten to place the maxheight into the taproot
> annex in order to address the issue with caching of script validity, then
> this auto-double-spend wallet would send every payment with an annex value
> that limits the payment to being valid only up to the next block.  If the
> payment doesn't make it into the next block, then resign it with the annex
> incremented to the next block, and repeat.
>
>
>> In a normal double spend scenario, there is no cost to a failed attempt,
>> but much to gain from a success. With your design, there is a real cost to
>> every single attempt (transaction fees) and no evidence that the rate of
>> success would be higher (you still have to bet on the reorg not including
>> your transaction in the first few blocks). It sounds like this new system
>> would actually be less attractive to double spenders than the current model!
>>
>> I also agree with Billy's idea for relay rules. We already have abusable
>> chain rules (e.g. a tx can be included in a block with 0 transaction fee
>> [spam?]) but we add protection with relay rules (e.g. minimum fee to
>> relay). I don't see how this would be any different, if the chain rules
>> only enforced the block height for confirmation and the relay rules forced
>> a minimum OP_BBV value in order to protect against reorg double spends.
>>
>
> The inclusion of a tx with 0 transaction fee in a block is not in of
> itself an abuse.  There is nothing wrong with blocks containing such
> transactions.  The *relay* of 0 transaction fee transactions is what is an
> abuse because it allows one to usurp Bitcoin's gossip network for their own
> arbitrary communications platform without cost.  Most Bitcoin users aren't
> signing up for being a usenet provider.  So, by policy, nodes require a
> cost to relay transactions so that broadcasting isn't free. Even when that
> price is paid to someone else, it still is an effective limitation on abuse.
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>

[-- Attachment #2: Type: text/html, Size: 5983 bytes --]

 permalink raw reply	[|nested]
2021-06-12  7:59             ` Billy Tetrud

  2021-06-12 18:48                 ` Billy Tetrud
  
From: Russell O'Connor @ 2021-06-12 15:58 UTC (permalink / raw)
  To: Billy Tetrud;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 3171 bytes --]

On Sat, Jun 12, 2021 at 3:59 AM Billy Tetrud <billy.tetrud@gmail•com> wrote:

> >  taproot annex
>
> From what I can tell, the annex is basically additional inputs to a script
> that might have additional constraints put on it. Is that right? I don't
> quite follow how moving the max height to the annex helps script caching
> here. I wasn't able to find much information on how the annex is envisioned
> to be used. Would you mind elaborating on how this would work?
>
> Also, I think the proposal as it stands already addresses script caching
> (in the Transaction Evaluation section
> <https://github.com/fresheneesz/bip-efficient-bitcoin-vaults/blob/main/bbv/bip-beforeblockverify.md#transaction-evaluation>).
> The result of the script can be cached as long as the cache item also
> contains information requiring just the OP_BBV to be re-evaluated (for the
> relevant block).
>

The normal approach for this problem would be a design that adds an "annex
field" (where the details on how to delimit annex fields is not yet
standardized) for a maxheight value, and add a consensus rule that
transaction with one (or more?) maxheight fields are invalid in blocks
whose height exceeds this (or any) maxheight value.  Then you could/would
add an OP code to push a copy of the (smallest) maxheight value from the
annex onto the stack or maybe an opcode to compare a stack item with this
(every) maxheight value from the annex.  This indirection is how OP_CLTV
and OP_CSV work and this indirection makes script validity cacheable
because script remains a function of the transaction data only.  Since
transaction data doesn't change, neither does the outcome of script
evaluation. The rule that invalidates late transactions looks only at the
annex and is independent of any script evaluation considerations.


> > this auto-double-spend wallet would send every payment with an annex value
> that limits the payment to being valid only up to the next block
>
> One possible solution to that would be to require that the input to OP_BBV
> to be in the script itself and not originate from the witness.
>
> Regardless, I think the ideal solution is to not have any of these such
> rules if we can simply change the definition for what counts as
> finalization to account for the fact that BBV transactions mined close to
> their expiration. Is there a reason this finalization-redefinition is not
> an adequate solution?
>

Generally speaking, you cannot solve security problems through optional and
completely voluntary transaction relay policy.  I'll just send my
about-to-expire transactions directly to miners and they will probably mine
them because they are, in fact, valid, and pay fees.  Why wouldn't they
mine it?

(Yes, I know this logic also applies to RBF flagged transactions.  Indeed,
you cannot rely on an RBF flag to prevent double spending,  Yes I think the
RBF flag ought to be removed from consideration and every transaction
should be considered RBFable.  Maybe that even happens to be my own node's
relay policy.)

I apologize, but I don't think I have further time to engage in an idea
that I don't consider likely to achieve broad community support.

[-- Attachment #2: Type: text/html, Size: 3984 bytes --]

 permalink raw reply	[|nested]
2021-06-12 15:58               ` Russell O'Connor

  2021-06-13 22:12                   ` Billy Tetrud
  
From: Billy Tetrud @ 2021-06-12 18:48 UTC (permalink / raw)
  To: Russell O'Connor;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 4535 bytes --]

>  I'll just send my about-to-expire transactions directly to miners and
they will probably mine them because they are, in fact, valid, and pay
fees.  Why wouldn't they mine it?

You've misunderstood me. When I said "change what counts as finalization",
what I meant is for the receiver of coins, not for mining or relay. For
example, if you buy coffee with an OP_BBV output that expires in the next
block, the merchant will be able to see that there's one confirmation on
your transaction. But they should also be able to see a warning saying that
the transaction has not finalized and they must wait for 6 confirmations
before treating payment as complete. This way, in the case that a reorg
happens and it doesn't contain the transaction, the merchant will not have
given the coffee yet, and their software will be able to tell them that the
payment has been reversed.

> I think the RBF flag ought to be removed from consideration and every
transaction should be considered RBFable

I agree with that. Making the assumption that a non-RBF transaction won't
be replaced isn't a great assumption.

> This indirection is how OP_CLTV and OP_CSV work

I see. Thanks for the explanation.


On Sat, Jun 12, 2021 at 8:58 AM Russell O'Connor <roconnor@blockstream•com>
wrote:

>
> On Sat, Jun 12, 2021 at 3:59 AM Billy Tetrud <billy.tetrud@gmail•com>
> wrote:
>
>> >  taproot annex
>>
>> From what I can tell, the annex is basically additional inputs to a
>> script that might have additional constraints put on it. Is that right? I
>> don't quite follow how moving the max height to the annex helps script
>> caching here. I wasn't able to find much information on how the annex is
>> envisioned to be used. Would you mind elaborating on how this would work?
>>
>> Also, I think the proposal as it stands already addresses script caching
>> (in the Transaction Evaluation section
>> <https://github.com/fresheneesz/bip-efficient-bitcoin-vaults/blob/main/bbv/bip-beforeblockverify.md#transaction-evaluation>).
>> The result of the script can be cached as long as the cache item also
>> contains information requiring just the OP_BBV to be re-evaluated (for the
>> relevant block).
>>
>
> The normal approach for this problem would be a design that adds an "annex
> field" (where the details on how to delimit annex fields is not yet
> standardized) for a maxheight value, and add a consensus rule that
> transaction with one (or more?) maxheight fields are invalid in blocks
> whose height exceeds this (or any) maxheight value.  Then you could/would
> add an OP code to push a copy of the (smallest) maxheight value from the
> annex onto the stack or maybe an opcode to compare a stack item with this
> (every) maxheight value from the annex.  This indirection is how OP_CLTV
> and OP_CSV work and this indirection makes script validity cacheable
> because script remains a function of the transaction data only.  Since
> transaction data doesn't change, neither does the outcome of script
> evaluation. The rule that invalidates late transactions looks only at the
> annex and is independent of any script evaluation considerations.
>
>
>> > this auto-double-spend wallet would send every payment with an annex value
>> that limits the payment to being valid only up to the next block
>>
>> One possible solution to that would be to require that the input to
>> OP_BBV to be in the script itself and not originate from the witness.
>>
>> Regardless, I think the ideal solution is to not have any of these such
>> rules if we can simply change the definition for what counts as
>> finalization to account for the fact that BBV transactions mined close to
>> their expiration. Is there a reason this finalization-redefinition is not
>> an adequate solution?
>>
>
> Generally speaking, you cannot solve security problems through optional
> and completely voluntary transaction relay policy.  I'll just send my
> about-to-expire transactions directly to miners and they will probably mine
> them because they are, in fact, valid, and pay fees.  Why wouldn't they
> mine it?
>
> (Yes, I know this logic also applies to RBF flagged transactions.  Indeed,
> you cannot rely on an RBF flag to prevent double spending,  Yes I think the
> RBF flag ought to be removed from consideration and every transaction
> should be considered RBFable.  Maybe that even happens to be my own node's
> relay policy.)
>
> I apologize, but I don't think I have further time to engage in an idea
> that I don't consider likely to achieve broad community support.
>

[-- Attachment #2: Type: text/html, Size: 5771 bytes --]

 permalink raw reply	[|nested]
2021-06-12 18:48                 ` Billy Tetrud

  
From: Billy Tetrud @ 2021-06-13 22:12 UTC (permalink / raw)
  To: Russell O'Connor;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 6276 bytes --]

I've thought of a third mitigation I think might be sufficient for you,
Russell, even if neither changing what receivers of coins define as a
finalized transaction nor disallowing block height from be specified by the
script witness are not sufficient for some reason.

Consider a rule increasing the weight of a transaction using OP_BBV by 1%
for each block within 100 blocks that the transaction is mined into. Eg, if
a spend-path using OP_BBV is mined into a block that is greater than 100
blocks before the expiry, no additional weight is added, if the block is
exactly 100 blocks from expiry the weight is increased by 1%, if the block
is 6 blocks away from expiry the weight is 2.54 times as large (1.01^94),
etc. This way, if someone tried to program the passive auto-double-spend
wallet, they'd have to spend over 2 times as much in fees as they would
otherwise. Also, since the increase in weight is only about 6% over the
span of 6 blocks, that is unlikely to affect the transaction's
profitability to mine much, so it would be ineffective to program the
auto-double-spend wallet to simply send transactions that expire within 101
blocks, because miners would highly likely still mine in that transaction
in subsequent blocks during a reorg.

In any case, I see 3 different solutions to the attack vector you brought
up (modifying receiver finalization definition, disallowing inputs to the
script to determine block height, and gradual transaction weight increase
near expiry). Any one of them seems to solve the problem you presented.

On Sat, Jun 12, 2021 at 11:48 AM Billy Tetrud <billy.tetrud@gmail•com>
wrote:

> >  I'll just send my about-to-expire transactions directly to miners and
> they will probably mine them because they are, in fact, valid, and pay
> fees.  Why wouldn't they mine it?
>
> You've misunderstood me. When I said "change what counts as finalization",
> what I meant is for the receiver of coins, not for mining or relay. For
> example, if you buy coffee with an OP_BBV output that expires in the next
> block, the merchant will be able to see that there's one confirmation on
> your transaction. But they should also be able to see a warning saying that
> the transaction has not finalized and they must wait for 6 confirmations
> before treating payment as complete. This way, in the case that a reorg
> happens and it doesn't contain the transaction, the merchant will not have
> given the coffee yet, and their software will be able to tell them that the
> payment has been reversed.
>
> > I think the RBF flag ought to be removed from consideration and every
> transaction should be considered RBFable
>
> I agree with that. Making the assumption that a non-RBF transaction won't
> be replaced isn't a great assumption.
>
> > This indirection is how OP_CLTV and OP_CSV work
>
> I see. Thanks for the explanation.
>
>
> On Sat, Jun 12, 2021 at 8:58 AM Russell O'Connor <roconnor@blockstream•com>
> wrote:
>
>>
>> On Sat, Jun 12, 2021 at 3:59 AM Billy Tetrud <billy.tetrud@gmail•com>
>> wrote:
>>
>>> >  taproot annex
>>>
>>> From what I can tell, the annex is basically additional inputs to a
>>> script that might have additional constraints put on it. Is that right? I
>>> don't quite follow how moving the max height to the annex helps script
>>> caching here. I wasn't able to find much information on how the annex is
>>> envisioned to be used. Would you mind elaborating on how this would work?
>>>
>>> Also, I think the proposal as it stands already addresses script caching
>>> (in the Transaction Evaluation section
>>> <https://github.com/fresheneesz/bip-efficient-bitcoin-vaults/blob/main/bbv/bip-beforeblockverify.md#transaction-evaluation>).
>>> The result of the script can be cached as long as the cache item also
>>> contains information requiring just the OP_BBV to be re-evaluated (for the
>>> relevant block).
>>>
>>
>> The normal approach for this problem would be a design that adds an
>> "annex field" (where the details on how to delimit annex fields is not yet
>> standardized) for a maxheight value, and add a consensus rule that
>> transaction with one (or more?) maxheight fields are invalid in blocks
>> whose height exceeds this (or any) maxheight value.  Then you could/would
>> add an OP code to push a copy of the (smallest) maxheight value from the
>> annex onto the stack or maybe an opcode to compare a stack item with this
>> (every) maxheight value from the annex.  This indirection is how OP_CLTV
>> and OP_CSV work and this indirection makes script validity cacheable
>> because script remains a function of the transaction data only.  Since
>> transaction data doesn't change, neither does the outcome of script
>> evaluation. The rule that invalidates late transactions looks only at the
>> annex and is independent of any script evaluation considerations.
>>
>>
>>> > this auto-double-spend wallet would send every payment with an annex value
>>> that limits the payment to being valid only up to the next block
>>>
>>> One possible solution to that would be to require that the input to
>>> OP_BBV to be in the script itself and not originate from the witness.
>>>
>>> Regardless, I think the ideal solution is to not have any of these such
>>> rules if we can simply change the definition for what counts as
>>> finalization to account for the fact that BBV transactions mined close to
>>> their expiration. Is there a reason this finalization-redefinition is not
>>> an adequate solution?
>>>
>>
>> Generally speaking, you cannot solve security problems through optional
>> and completely voluntary transaction relay policy.  I'll just send my
>> about-to-expire transactions directly to miners and they will probably mine
>> them because they are, in fact, valid, and pay fees.  Why wouldn't they
>> mine it?
>>
>> (Yes, I know this logic also applies to RBF flagged transactions.
>> Indeed, you cannot rely on an RBF flag to prevent double spending,  Yes I
>> think the RBF flag ought to be removed from consideration and every
>> transaction should be considered RBFable.  Maybe that even happens to be my
>> own node's relay policy.)
>>
>> I apologize, but I don't think I have further time to engage in an idea
>> that I don't consider likely to achieve broad community support.
>>
>

[-- Attachment #2: Type: text/html, Size: 7780 bytes --]

 permalink raw reply	[|nested]