Avoiding Stuck Transactions With BitGo
A lot happens under the hood when sending a Bitcoin transaction - I covered some of the details in a previous post about the challenges of UTXO selection. After managing BitGo's outgoing transaction queue for the past year, I have a few observations to make.
Most wallet software is not yet in a state that makes it easy for end users to manage sending Bitcoin transactions. I've seen many a post on Reddit where a confused user asks "why isn't my transaction confirming after several hours or days?" and until a more experienced user comes along and explains the problem, Bitcoin is basically broken from their perspective. Even after they understand the problem, it's usually too late for the user to fix.
It's clear from observing the transactions on the network that most Bitcoin users are using wallets that still do not have dynamic fee support. Most transactions are currently setting fees that are exact multiples of 0.0001 BTC. They are clearly hard coded fees - this is the wrong approach. Instead of targeting a flat fee of 0.000x BTC, wallets should be targeting a fee rate based upon the data size of the transaction and the current fee market conditions. You can read more about BitGo's dynamic fees in our post about surge pricing. If you're a high volume sender, we can probably save you a lot of money!
Spending unconfirmed outputs is also a common pitfall users run into. When you spend an unconfirmed output, you're ensuring that your transaction won't confirm until the parent transaction is also confirmed, which might never happen for a number of reasons. We default our web client to not spend unconfirmed outputs, though some API users still do so against our recommendation. Our monitoring will catch these transactions so that we can alert the user with proof of why they should not engage in this activity. In some cases we may be able to leverage our mining connections to get the transaction(s) confirmed.
Users can also inadvertently run into issues that they don't understand, such as long transaction chains. Long chains are dangerous for several reasons:
- You're creating dependencies, so if anything goes wrong with one transaction in the chain, all of the descendants will get stuck and won't confirm until the parent gets confirmed. This can occur due to sudden spikes in the transaction fee market or it could happen if a malleated version of the transaction gets confirmed, which would invalidate all of the descendants.
- As of Bitcoin Core 0.12, which was just released, nodes will stop relaying long chains of transactions. Now unconfirmed chains more than ~10 transactions long (depending upon their total data size) won't get relayed. This will also slow down how quickly your transactions get confirmed.
We've found that BitGo users who create long chains of transactions are doing so because they don't have enough unspent outputs in their wallet. This is why we developed a "change splitting" feature that our API users can enable to automatically create more change outputs if their wallet falls below our recommended threshold for their activity. The benefits of having more available confirmed unspent outputs to choose from are be faster confirmation times and robustness against edge case issues described above.
On the opposite end of the spectrum, some BitGo users have too many low value unspent outputs in their wallet, which makes it a challenge to send higher value transactions. As a result, we developed an unspent output consolidation tool that our API users can configure to clean up their wallet on a regular basis.
Depending on the dynamics of a particular hot wallet, it may be necessary to enable either change-splitting, periodic consolidation, or both. Smartly managing the unspent output set is by far the most important factor in ensuring a smoothly functioning hot wallet.
Using a Bitcoin wallet that has a send queue managed by experts can add value to your user experience by helping you avoid technical pitfalls. Contact us today if you want to make your transaction sending easier, faster, and cheaper!