public inbox for bitcoindev@googlegroups.com
 help / color / mirror / Atom feed
From: Tom Harding <tomh@thinlink.com>
To: Peter Todd <pete@petertodd.org>,
	 Bitcoin Dev <bitcoin-development@lists.sourceforge.net>
Subject: Re: [Bitcoin-development] First-Seen-Safe Replace-by-Fee
Date: Tue, 26 May 2015 10:54:05 -0700	[thread overview]
Message-ID: <5564B33D.3070107@thinlink.com> (raw)
In-Reply-To: <20150526051305.GA23502@savin.petertodd.org>


I think this is a significant step forward.

I suggest you also need to ensure that no inputs can be removed or 
changed (other than scriptsigs) -- only added.  Otherwise, the semantics 
change too much for the original signers.  Imagine a tx with two inputs 
from different parties.  Should it be easy for party 1 to be able to 
eliminate party 2 as a contributor of funds?  It's not difficult to 
imagine real-world consequences to not having contributed to the 
transaction.  And unless you can think of a reason, tx-level attributes 
like nLocktime should not change either.

The result would be something very like CPFP, but with the new inputs 
and outputs merged into the original tx, keeping most of the overhead 
savings you describe.

It should be submitted to bitcoin/bitcoin because like most inconsistent 
relay policies, inconsistently deployed FSS RBF invites attacks (see 
https://gist.github.com/aalness/a78e3e35b90f52140f0d).

Generally, to be kind to zeroconf:

  - Align relay and validation rules
  - Keep first-seen
  - Relay double-spends as alerts
  - Allow nLocktime transactions into the mempool a bit before they 
become final
  - ...

It's not unlike making a best-effort to reduce sources of malleability.  
FSS RBF should be compatible with this if deployed consistently.



On 5/25/2015 10:13 PM, Peter Todd wrote:
> Summary
> -------
>
> First-seen-safe replace-by-fee (FSS RBF) does the following:
>
> 1) Give users effective ways of getting "stuck" transactions unstuck.
> 2) Use blockchain space efficiently.
>
> without:
>
> 3) Changing the status quo with regard to zeroconf.
>
> The current Bitcoin Core implementation has "first-seen" mempool
> behavior. Once transaction t1 has been accepted, the transaction is
> never removed from the mempool until mined, or double-spent by a
> transaction in a block. The author's previously proposed replace-by-fee
> replaced this behavior with simply accepting the transaction paying the
> highest fee.
>
> FSS RBF is a compromise between these two behaviors. Transactions may be
> replaced by higher-fee paying transactions, provided that all outputs in
> the previous transaction are still paid by the replacement. While not as
> general as standard RBF, and with higher costs than standard RBF, this
> still allows fees on transaction to be increased after the fact with
> less cost and higher efficiency than child-pays-for-parent in many
> common situations; in some situations CPFP is unusable, leaving RBF as
> the only option.
>
>
> Semantics
> ---------
>
> For reference, standard replace-by-fee has the following criteria for
> determining whether to replace a transaction.
>
> 1) t2 pays > fees than t1
>
> 2) The delta fees pay by t2, t2.fee - t1.fee, are >= the minimum fee
>     required to relay t2. (t2.size * min_fee_per_kb)
>
> 3) t2 pays more fees/kb than t1
>
> FSS RBF adds the following additional criteria to replace-by-fee before
> allowing a transaction t1 to be replaced with t2:
>
> 1) All outputs of t1 exist in t2 and pay >= the value in t1.
>
> 2) All outputs of t1 are unspent.
>
> 3) The order of outputs in t2 is the same as in t1 with additional new
>     outputs at the end of the output list.
>
> 4) t2 only conflicts with a single transaction, t1
>
> 5) t2 does not spend any outputs of t1 (which would make it an invalid
>     transaction, impossible to mine)
>
> These additional criteria respect the existing "first-seen" behavior of
> the Bitcoin Core mempool implementation, such that once an address is
> payed some amount of BTC, all subsequent replacement transactions will
> pay an equal or greater amount. In short, FSS-RBF is "zeroconf safe" and
> has no affect on the ability of attackers to doublespend. (beyond of
> course the fact that any changes what-so-ever to mempool behavior are
> potential zeroconf doublespend vulnerabilities)
>
>
> Implementation
> --------------
>
> Pull-req for git HEAD: https://github.com/bitcoin/bitcoin/pull/6176
>
> A backport to v0.10.2 is pending.
>
> An implementation of fee bumping respecting FSS rules is available at:
>
> https://github.com/petertodd/replace-by-fee-tools/blob/master/bump-fee.py
>
>
> Usage Scenarios
> ---------------
>
> Case 1: Increasing the fee on a single tx
> -----------------------------------------
>
> We start with a 1-in-2-out P2PKH using transaction t1, 226 bytes in size
> with the minimal relay fee, 2.26uBTC. Increasing the fee while
> respecting FSS-RBF rules requires the addition of one more txin, with
> the change output value increased appropriately, resulting in
> transaction t2, size 374 bytes. If the change txout is sufficient for
> the fee increase, increasing the fee via CPFP requires a second
> 1-in-1-out transaction, 192 bytes, for a total of 418 bytes; if another
> input is required, CPFP requires a 2-in-1-out tx, 340 bytes, for a total
> of 566 bytes.
>
> Benefits: 11% to 34%+ cost savings, and RBF can increase fees even in
>            cases where the original transaction didn't have a change
>            output.
>
>
> Case 2: Paying multiple recipients in succession
> ------------------------------------------------
>
> We have a 1-in-2-out P2PKH transaction t1, 226 bytes, that pays Alice.
> We now need to pay Bob. With plain RBF we'd just add a new outptu and
> reduce the value of the change address, a 90% savings. However with FSS
> RBF, decreasing the value is not allowed, so we have to add an input.
>
> If the change of t1 is sufficient to pay Bob, a second 1-in-2-out tx can
> be created, 2*226=452 bytes in total. With FSS RBF we can replace t1
> with a 2-in-3-out tx paying both, increasing the value of the change
> output appropriately, resulting in 408 bytes transaction saving 10%
>
> Similar to the above example in the case where the change address of t1
> is insufficient to pay Bob the end result is one less transaction output
> in the wallet, defragmenting it. Spending these outputs later on would
> require two 148 byte inputs compared to one with RBF, resulting in an
> overall savings of 25%
>
>
> Case 3: Paying the same recipient multiple times
> ------------------------------------------------
>
> For example, consider the situation of an exchange, Acme Bitcoin Sales,
> that keeps the majority of coins in cold storage. Acme wants to move
> funds to cold storage at the lowest possible cost, taking advantage of
> periods of higher capacity. (inevitable due to the poisson nature of
> block creation) At the same time they would like to defragment their
> incoming outputs to keep redemption costs low, particularly since
> spending their high-security 3-of-7 P2SH multisigs is expensive. Acme
> creates a low fee transaction with a single output to cold storage,
> periodically adding new inputs as funds need to be moved to storage.
> Estimating the cost savings here is complex, and depends greatly on
> details of Acme's business, but regardless the approach works from a
> technical point of view. For instance if Acme's business is such that
> the total hotwallet size needed heavily depends on external factors like
> volatility, as hotwallet demand decreases throughout a day they can add
> inputs to the pending transaction. (simply asking customers to deposit
> funds directly to the cold storage is also a useful strategy)
>
> However this is another case where standard RBF is significantly more
> useful. For instance, as withdrawal requests come in the exchange can
> quickly replace their pending transactions sending funds to cold storage
> with transactions sending those funds to customers instead, each time
> avoiding multiple costly transactions. In particular, by reducing the
> need to access cold storage at all, the security of the cold-stored
> funds is increased.
>
>
> Wallet Compatibility
> --------------------
>
> All wallets should treat conflicting incoming transactions as equivalent
> so long as the transaction outputs owned by them do not change. In
> addition to compatibility with RBF-related practices, this prevents
> unnecessary user concern if transactions are mutated. Wallets must not
> assume TXIDs are fixed until confirmed in the blockchain; a fixed TXID
> is not guaranteed by the Bitcoin protocol.
>
>




  reply	other threads:[~2015-05-26 18:22 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-26  5:13 [Bitcoin-development] First-Seen-Safe Replace-by-Fee Peter Todd
2015-05-26 17:54 ` Tom Harding [this message]
2015-05-26 19:10   ` Gregory Maxwell
2015-05-26 23:00     ` Tom Harding
2015-05-26 23:11       ` Gregory Maxwell
2015-05-26 23:42         ` Tom Harding
2015-05-26 21:20 ` Danny Thorpe
2015-05-26 21:27   ` Pieter Wuille
2015-05-26 22:09     ` Danny Thorpe
2015-05-26 22:18       ` Adam Back
2015-05-27  7:30 ` Peter Todd
2015-06-10  9:10 ` [Bitcoin-development] First-Seen-Safe Replace-by-Fee patch against Bitcoin Core v0.10.2 Peter Todd

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5564B33D.3070107@thinlink.com \
    --to=tomh@thinlink.com \
    --cc=bitcoin-development@lists.sourceforge.net \
    --cc=pete@petertodd.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox