# Introduction to Replace-By-Fee (RBF) in Ledger-live

## 1. Replace-By-Fee (RBF)
RBF is a mechanism in the Bitcoin network that allows a sender to replace an already transmitted transaction with a new one that usually has a higher fee. This feature was introduced to address the issue of unconfirmed transactions lingering due to low fees. With RBF, a user can essentially "bump" the transaction by increasing the fee, encouraging miners to prioritize it for confirmation.

## 2. Double Spending Attack with RBF
The interplay between RBF and Double Spending is critical. RBF, while solving the problem of stuck transactions, also potentially enables a form of double spending. For instance, a fraudster could make a transaction to a merchant and subsequently replace it with another transaction to a different address with a higher fee. If the second transaction gets confirmed first, the merchant would not receive the intended funds, falling victim to double spending.

## 3. RBF Implementation in Ledger-Live
Ledger-live's implementation of RBF only realizes a part of Bitcoin Core's functionality. Currently, we cannot execute a transaction's speed up and cancel via Ledger-live. If there's a need for speeding up or canceling transactions, we generally recommend users to employ a third-party wallet, like Electrum. However, we have reserved the corresponding data structure to support RBF, so it's possible to implement this feature in future versions.

For a transaction obtained from a blockchain explorer, all inputs of this transaction have a sequence field. If this field is `0xffffffff`, then the transaction cannot be replaced.

If a transaction can be replaced, we mark all UTXOs generated by this transaction as `rbf: true`. Please refer to the Input and Output data structure defined in `bitcoin/wallet-btc/storage/types.ts`.

When sending a transaction using Ledger-live, in `js-buildTransaction.ts`, we call `wallet.buildAccountTx` to construct the transaction. It contains a `sequence` parameter, which can be adjusted (0 or 0xffffffff) to determine whether the transaction to be sent can be replaced.

Currently, when user sends a transaction via LLD/LLM, we directly pass the sequence as 0, so the transactions we send can be replaced. (In older versions of LLD and LLM, users could choose whether the transaction is RBF, but this was simplified due to UI complexity.)

## 4. Calculating MaxSpendable
Due to the presence of RBF, when a transaction has not been written into a block, we prefer not to spend UTXOs generated by this transaction in LLD and LLM, due to the risk of the aforementioned "Double Spending Attack with RBF". Therefore, when calculating MaxSpendable, we filter out all UTXOs of unconfirmed transactions. However, there is an exception - when the UTXO is a change, we allow users to spend it because only the user themselves can cancel/replace the transaction, eliminating the risk of being attacked by Double Spending.

The above logic for calculating MaxSpendable is implemented in the `estimateAccountMaxSpendable` function in `bitcoin/wallet-btc/wallet.ts`.

Apart from unconfirmed UTXOs, users can also manually filter out some UTXOs on the LLD/LLM UI interface. The new transaction will not spend these UTXOs. Filtering out these UTXOs will change the value of MaxSpendable. This is what the `excludeUTXOs` parameter in the `estimateAccountMaxSpendable` function does.
