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

Limit "send all" batches to policy weight limit and fix estimated weight limit calculation #708

Closed
wants to merge 4 commits into from

Conversation

pinheadmz
Copy link
Member

This PR fixes a few related wallet bugs including a new one I hadn't noticed before.

  1. If a user tries to revealAll or redeemAll with too many BIDs (like around 600) the resulting transaction will be too big to send, violating the relay policy weight limit. This is a big issue because loss of funds can occur if reveals are not sent in time. The solution is to recalculate the estimated weight of the batch as we are building it, and break before the result is too heavy.

TODO:

  • test for multisig
  • should this be applied to regular sendReveal and sendRedeem as well? (They also produce batches)
  1. Once the batch has hit the limit and stops adding outputs, there may be a number of BIDs still unrevealed or unredeemed in the wallet. We want the user to be able to send those in another batch right away. However, they would encounter the "Could not resolve preferred inputs" error because the second batch would try to double-spend outputs in the first batch. This error is common when users reveal a single name and then call revealAll before that first single reveal has confirmed. The solution is pretty simple: when we add reveals to a batch, we skip over outputs that are marked as spent already in txdb. This required the addition of a new wallet function getUnspentCoin()

  2. While working with the TX size estimator to detect policy weight limit breaches, I noticed the MTX size estimator had unfinished bugs left over from its port from Bitcoin. In particular, we were not applying the witness discount to the scripts and signatures in multisig transactions. If you try to send a multisig transaction right now with master branch, you'll pay almost 100% extra fee because the estimator incorrectly computes a way bigger virtual size. The solution was to tweak the size estimator functions both in wallet.js and mtx.js. Also, since HNS signatures are fixed size (always 65 bytes as opposed to Bitcoin's 70-73 bytes) the estimator functions can be dialed in to almost always guaranteed accuracy. Tested.

- apply witness discount to multisig spends
- fix "fallback" 2-of-3 script hash size value
- account for large multisig scripts in script size varInt size
This will prevent the "Could not resolve preferred inputs" error
that is thrown when a user sends a single reveal followed by a
revealAll
@pinheadmz
Copy link
Member Author

Related upstream work: bcoin-org/bcoin#858

* Unlike Bitcoin, our signatures are always 65 bytes.
* However, we still assume that the witness varInt size
* is only one byte. In short, this estimate may be off
* by 1 (at most) but only if a witness has > 253 items.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...actually if the witness stack is too big, this varInt will be 3 bytes so off by 2 at most.

@Anunayj Anunayj added bug general - Something isn't working wallet part of the codebase tests part of the codebase labels Apr 29, 2022
@pinheadmz pinheadmz closed this Aug 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug general - Something isn't working tests part of the codebase wallet part of the codebase
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants