Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Watchtowers utxo pool and insufficient funds for being able to fee-bump revocation transactions #16

Open
darosior opened this issue Aug 20, 2020 · 13 comments
Assignees
Labels
RFC This needs to be discussed at a higher level

Comments

@darosior
Copy link
Member

I'll remove the FIXME in messages.md to move it here for a broader reflexion about this case. There are input from @JSwambo in https://github.com/re-vault/practical-revault/pull/1.

Long story short: the number of different vaults a watchtower can track is limited by its available funds, otherwise it could not be able to handle the worst case scenario (revault all unvault transactions of all vaults).

Note that it is also inherently limited by feerate increase (as we can't bet on future feerate)... Is it the fractional reserve of tomorrow ?

@darosior
Copy link
Member Author

darosior commented Oct 9, 2020

Ok, this've been here for almost 2 months. Now we need to discuss the actual UX of refilling the watchtower wallet as it has been brought up during the UI meeting.

I'd like to discuss this during Monday's meeting @kloaec @JSwambo @edouardparis so please give it some thoughts.

@darosior
Copy link
Member Author

darosior commented Oct 9, 2020

@darosior
Copy link
Member Author

darosior commented Oct 13, 2020

@JSwambo pointed in #28:

I'd like to note our working assumption here:

A busy mempool and high fee-rate can occur at any time and so watchtowers must always be prepared. This means actively maintaining their fee-bumping UTXO pool.

There are a few open questions here:

What is a sufficient amount of funds per vault UTXO, and how should these be distributed in a the fee-bump UTXO pool?
Is it necessary for each watchtower to maintain 100% collateral for the entire set of vault UTXO?
Given the two mechanisms for re-filling a watchtowers fee-bump UTXO pool (through change outputs and through routine signing ceremonies), can this process be practical and automatic?

Half-baked idea:

What if we enable co-operation between watchtowers? So WT1 broadcasts an RBF fee-bump tx signed with ANYONECANPAY|ALL. The fee-rate spikes and invalidates it. WT2 notices this transaction in the mempool and bumps the fee again.

@darosior
Copy link
Member Author

This means actively maintaining their fee-bumping UTXO pool.

Yes. And in practice have some breathing room.

What is a sufficient amount of funds per vault UTXO, and how should these be distributed in a the fee-bump UTXO pool?

I think that the entire utxo pool of each watchtower must satisfy:

total_balance >= breathing_room * n * ( max(cancel_tx_size, emer_tx_size) + fee-bumping_tx_size) * current_top_feerate

So, ideally each utxo would satisfy:

utxo_value >= breathing_room * ( max(cancel_tx_size, emer_tx_size) + fee-bumping_tx_size) * current_top_feerate

However, while it seems really intricate to keep this satisfied for the total_balance as the current_top_feerate moves, it is (i think) completely unreasonable to try to keep it for each utxo.

In addition, and in case of massive breakdown, a fee-bumping transaction can be batched, ie:

------------------------------------------------------------
big wallet utxo   |    first vault fee bumping utxo
-------------------------------------------------------------
                          |   second one
-------------------------------------------------------------
                          |   third  one
-------------------------------------------------------------
                          |   change
-------------------------------------------------------------

That confirms in (hopefully!) one block and then you have the entire remaining CSV time to make the revaulting txs to confirm.

I (and @edouardparis) mentioned the importance of a pool of utxos yesterday, but it therefore may not be a requirement. Let's already figure out a way to keep this total balance decently high enough.

Is it necessary for each watchtower to maintain 100% collateral for the entire set of vault UTXO?

For each in-house WT, I think so.

Given the two mechanisms for re-filling a watchtowers fee-bump UTXO pool (through change outputs and through routine signing ceremonies), can this process be practical and automatic?

I don't think we should seriously consider the unvault outputs i mention in #28.
Signing ceremonies, well, cannot be automatic. They are also admittedly quite a burden.

What if we enable co-operation between watchtowers?

Conceptually, that seems to be a red herring: they do not trust each other. The only intent of a WT might be to pin your transactions.

So WT1 broadcasts an RBF fee-bump tx signed with ANYONECANPAY|ALL

It'll always broadcast it with a ALL-signed feebump input attached.

WT2 notices this transaction in the mempool and bumps the fee again.

Huh? WT2 already has this transaction, hopefully ! Otherwise one participant is not protected.


In addition to the great questions by Jacob, i'd like to share some thoughts regarding specific issues we mentioned yesterday.

Duplication of the collateral

We don't support it yet, but each party will eventually have/hire multiple watchtowers. Does this mean the 100% reserve must be timed by the number of watchers ?

Not necessarily if they are ran by the same entity:

  • Watchtowers (hot) HD wallets can be duplicated (yeah, yeah).
  • At the end of the day, only one fee is claimed by the miner. Therefore i don't think one entity needs n * 100% reserve (with n watchtowers) even without wallet duplication and in case of outage. This however assumes that they are all running... Argh.

Refill

We mentioned refilling the WT utxo pool / wallet. This imposes a burden on the participants already. So instead, let's encourage consolidation ? Better for everyone.
How can this be accomplished:

  • Ceremonies.
  • Make each unvault use two Unvault Transactions: this way you can batch the spend transaction and create only one change vault utxo, by having spent two.

Note however the (practical) requirement for the bypass feature which, as we agreed in #21, should not be used for normal operations.

@darosior
Copy link
Member Author

darosior commented Oct 13, 2020

Another question brought up by Edouard:
Shoudl the stakeholder have a direct channel with its WT for refilling through revaultd / the GUI ?

@JSwambo
Copy link
Member

JSwambo commented Oct 22, 2020

However, while it seems really intricate to keep this satisfied for the total_balance as the current_top_feerate moves, it is (i think) completely unreasonable to try to keep it for each utxo.

We could argue over current_top_feerate being necessary, and could spend time doing statistical analyses to quantify the risk involved here. I think a separate important point is that whatever parameter we use should not be game-able -> the fee should not be able to be increased by a competitor paying a ridiculous fee on a single transaction.

In addition, and in case of massive breakdown, a fee-bumping transaction can be batched, ie:

Yeah I think that should be supported.

Is it necessary for each watchtower to maintain 100% collateral for the entire set of vault UTXO?

For each in-house WT, I think so.

Agreed.

I don't think we should seriously consider the unvault outputs i mention in #28.

I think it's a big risk to allow the software to have additional outputs that go to 'external wallets'. There would have to be another layer of (distributed) validation of the un-vault tx (from each stakeholder or their WT). I think it would require WTs knowing eachother's xpub and that being very difficult to spoof. Yeah... seems like a can of worms...

Signing ceremonies, well, cannot be automatic. They are also admittedly quite a burden.

... Perhaps its the same situation with the signing routine though. We need to think through the whole process and how it fits into the routine...

Refill

We mentioned refilling the WT utxo pool / wallet. This imposes a burden on the participants already. So instead, let's encourage consolidation ? Better for everyone.
How can this be accomplished:

* Ceremonies.

By this you mean independent refill ceremonies?

* Make each unvault use two Unvault Transactions: this way you can batch the spend transaction and create only one change vault utxo, by having spent two.

And here you mean create a parallel unvault/spend process (with every spend) that also sends funds to a WT? Not sure I fully understand...

@JSwambo
Copy link
Member

JSwambo commented Oct 22, 2020

Shoudl the stakeholder have a direct channel with its WT for refilling through revaultd / the GUI ?

They'd have to maintain their own independent wallet to do this. Might be a good way around requiring ceremonies. Is it less of a burden for each stakeholder?

@darosior
Copy link
Member Author

darosior commented Oct 22, 2020

could spend time doing statistical analyses to quantify the risk involved here.

We could, but let's not waste time to only get out with another arbitrary value that's going to be blown up anyways during the next bull run.

I think a separate important point is that whatever parameter we use should not be game-able -> the fee should not be able to be increased by a competitor paying a ridiculous fee on a single transaction.

That's not possible, or Bitcoin would not work. The best we can do is forcing them to pay a higher fee in order to "attack" us. There is no real attack on the funds tho.

... Perhaps its the same situation with the signing routine though. We need to think through the whole process and how it fits into the routine...

I'd argue that a stakeholder being used to re-sign transaction is a threat. Passive attacks work here.

By this you mean independent refill ceremonies?

No, consolidation ceremonies.. that's the point..
But i dislike this too: this makes the bypass being a normal feature

And here you mean create a parallel unvault/spend process (with every spend) that also sends funds to a WT? Not sure I fully understand...

Think of it as an active consolidation. Trying to draw it here:

Current model

  • We have 5 vaults
  • We unvault (the operation not the tx name!)
                                                                      __ external utxo
deposit utxo  ====> [unvault transaction] ====> [spend transaction] /
                                                                    \__ deposit utxo (change)
  • We now still have 5 vaults to watch.

My proposition

  • We have 5 vaults
  • We unvault (the operation not the tx name!)
deposit utxo  ====> [unvault transaction] ____                                         __ external utxo
                                               \_______   ====> [spend transaction]  /
                                                   ____/                             \ __ deposit utxo (change)
sec deposit utxo  ====> [sec unvault transaction] /
  • We now have 4 vaults to watch, we effectively consumed one and therefore reduced the watching cost by 20%

@JSwambo
Copy link
Member

JSwambo commented Oct 22, 2020

We could, but let's not waste time to only get out with another arbitrary value that's going to be blown up anyways during the next bull run.

Agreed! It can always be done at a later stage.

That's not possible, or Bitcoin would not work. The best we can do is forcing them to pay a higher fee in order to "attack" us. There is no real attack on the funds tho.

I just mean the current_top_feerate choice shouldn't be automatically updated if some Tx has a ridiculous fee paid on it. That's game-able.

* We now have 4 vaults to watch, we effectively consumed one and therefore reduced the watching cost by 20%

Something like this will definitely be necessary. Perhaps the distribution of vault UTXOs can be managed incrementally, and targeting an amount that is determined by the operational capacity of the WTs (all this predefined, not determined on the fly).

@darosior
Copy link
Member Author

TODO(darosior): talk about the discussion re inactive vaults

@darosior darosior added RFC This needs to be discussed at a higher level and removed Meeting labels Nov 10, 2020
@kloaec
Copy link
Member

kloaec commented Nov 12, 2020

As discussed IRL:
going for only a small number (many factors here, different for each client) of presigned unvault tx makes sense.

This still leaves the question of a "secured" vault with an emergencyTx but no UnvaultTx: how do we deal with the Emergency fees?

I'm really not confident with consolidating vaults into a very few UTXOs as the risk is higher when they are Active, but the fee management for both Active and Secured is really easier/cheaper/more realistic from a mempool space available perspective.

@darosior
Copy link
Member Author

We can also consolidate using a higher threshold (eg don't go higher than X vaults in fly) and transcribe it in the coin control screen (h/t @edouardparis)

@JSwambo
Copy link
Member

JSwambo commented Nov 15, 2020

Problem: Watchtower re-fills are cumbersome/ impractical. Can minimize them with the following approach.

This idea doesn't prevent the fundamental problems of fee-market spike.

Consider 'vault' as any combination of deposit UTXOs that are secured/ active.

Limits:

  • Each vault requires a watchtower to be ready with sufficient fees to push the emergency/ cancel transaction -> Max number of vaults is a function of watchtower capital.
  • Custodians may want to limit the value of each vault, to avoid having too much 'active' at any time -> Max value of vaults is a function of risk preference
  • Routine signing ceremony required if vaults are re-grouped. This should (maybe?) be avoided completely as it is too much complexity (deleting pre-signed transactions for 'old vaults'). -> vaults (sets of deposit UTXOs) are constant until consumed.

Algo

How to handle deposits that increase the number of vaults (potentially above capacity)?
1. Group deposit UTXOs into a vault_buffer until the value is close to max value of vault.
2. Next deposit would overflow vault_buffer, so requires vault_buffer to be flushed (DBs define buffer as 'vault-able' and prepare it for next signing ceremony).
3. Next deposit into now empty vault_buffer and repeat 1 & 2 until number of vaults exceeds Max number of vaults.
4. Complain when receiving deposit that there is not enough WT capital if the number of vaults would exceed max. "New deposits cannot be secured until WT has sufficient fees". Note that number of vaults decreases with spends since change from spends will likely not overflow vault_buffer every time. Note that if a cancel occurs, WT capital is drained and the vault_buffer would be immediately filled, requiring WT to be re-filled.

Number of vaults x Value of vaults =< WT required capital

  • Since Number of vaults is variable, WT requires excess capital to account for rate of increase.

  • The inputs' amounts are variable in unvault txs, corresponding to the value flushed from vault_buffers. The outputs amounts may be static (with change becoming deposit UTXOs)

  • 'Required capital' is filled with uncertainty due to fee market dynamics.

  • 'Excess capital' is uncertain if std deviation of number of vaults is unknown/ unknowable. Perhaps a Bayesian approach to estimation works here (for custodians with somewhat regular flows)

Requirements:

  • Unvault Tx batches deposit UTXOs
  • Emergency Tx batches same deposit UTXOs
  • DB for each wallet needs to be consistent about how deposit UTXOs are grouped into vaults (deterministic algo)
  • WT requires re-fill after each cancel.
  • Impossible to avoid black swan events, so a manual fallback is required if fee market skyrockets.
    1. Funds go from 'secured' -> 'deposit' if WT fees are no longer sufficient.
    2. Stks are warned that the bitcoin network is highly active and that the cost of their operation needs to increase.
    3. ... ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
RFC This needs to be discussed at a higher level
Projects
None yet
Development

No branches or pull requests

4 participants