client/asset/{btc,dcr}: enable split funding transactions#562
Conversation
| // related variation as well as a potential dust change output with no | ||
| // subtractee specified, in which case the dust goes to the miner. | ||
| if checkRate > feeRate*3 { | ||
| if changeAdded && checkRate > feeRate*3 { |
There was a problem hiding this comment.
With the changes in TestAvailableFund, I actually ran up against the *3 when the change was a dust ouptut. *3 was 69 atoms/byte and the effective rate ended up being 71. I'm sure we could improve this still.
| // Add funding for an extra input to accommodate the later combined tests. | ||
| lottaFunds := calc.RequiredOrderFunds(lottaOrder, 2*dexdcr.P2PKHInputSize, tDCR) |
There was a problem hiding this comment.
This was a little counterintuitive, so I figured I would mention it. Combining littleFunds + lottaFunds is not enough to cover extraLottaOrder = littleOrder + lottaOrder, even though littleFunds is enough to cover littleOrder and lottaFunds is enough to cover lottaOrder.
In English: you must prove ownership of fewer funds in order to place two one lot orders than you would to place one two lot order with two inputs.
In Go:
func TestThis(t *testing.T) {
one := calc.RequiredOrderFunds(tBTC.LotSize, dexbtc.RedeemP2PKHInputSize, tBTC)
two := calc.RequiredOrderFunds(2*tBTC.LotSize, 2*dexbtc.RedeemP2PKHInputSize, tBTC)
fmt.Println("one =", one, ", two =", two, ", two <= one*2 ?", two <= one*2)
}will print one = 1007650 , two = 2020366 , two <= one*2 ? false.
There was a problem hiding this comment.
Since we talked about market and immediate limit orders (orders that don't sit on the book indefinitely) not really needing the split txn, I figure we'll eventually want a "use split tx" button on the order dialog with the default set according to the wallet's config. Alternatively or in addition to the per-order option, I can imagine two wallet settings rather than one: use split tx for (1) standing/bookable orders, and (2) unbookable orders like market and immediate force. I bring it up in this PR because useSplitTx is an ExchangeWallet field set on construction, but if it is made a per-order option it would need to be an input arg to FundOrder, and if there were two options pertaining to bookability then that would preclude an ExchangeWallet config field altogether since order type is not something ExchangeWallet knows about at all.
| // NOTE: Can't return coins yet, because dcrwallet doesn't recognize them as | ||
| // spent immediately, so subsequent calls to FundOrder might result in a | ||
| // `-4: rejected transaction: transaction in the pool already spends the | ||
| // same coins` error. |
There was a problem hiding this comment.
That's unfortunate. What does it seem dcrwallet needs to recognize them as spent? Just a little time? I guess for now we just leave them locked forever, or at least until dexc restart? This is what logSplitFunds and the map is for now I see.
| { | ||
| Key: "txsplit", | ||
| DisplayName: "Pre-split funding inputs", | ||
| Description: "Pre-split funding inputs to prevent locking funds into an order for which a change output may not be immediately available. Only used for standing-type orders.", |
There was a problem hiding this comment.
Maybe "to prevent locking excess funds".
I get that "change output may not be immediately available" refers to when the swap contract txn happens shortly after the order placement, thus making the change available, but it's unlikely most users will get that. Plus, even if they did get that, they should understand that a swap could take hours (esp. taker waiting for maker's swap before broadcasting their own). How about something more accessible to average users like When placing an order, create a "split" transaction to fund the order without locking more of the wallet balance than necessary. Otherwise, excess funds may be reserved to fund the order until the swap contract transaction is created during trade settlement or the order is canceled. This an extra transaction for which network mining fees are paid. Most useful for standing-type orders that may remain on the book indefinitely.
Also, it currently seems to be used for all trade orders, not just standing.
There was a problem hiding this comment.
Also, it currently seems to be used for all trade orders, not just standing.
Oh yeah. I had a solution working for this, but backed off for some reason. I'll get it in now.
There was a problem hiding this comment.
So adding asset-specific order options is probably doable, but a large undertaking. For now, I'm just informing the ExchangeWallet whether the funds are for a standing or immediate order, and the funds aren't being split if it's immediate. See aa5fc57.
|
An interesting consequence of the split tx is that the init/contract txn is less likely to have change, thus the user ends up paying maxFeeRate or higher much of the time. e.g. Here's a DCR swap contract txn spending the output of a split tx: It omitted the change output because it would have been dust (presumably). The init txn above is 214 bytes, with a 8032 atom fee, for a fee rate of ~37.5 atoms/B.
I'm gonna test some more splits, but it seems to be working. |
|
BTC on the other hand is massively over allocating. A 2 lot (20 DCR lot size) buy order:
Anyway, for this level of fee over-allocation, the swap txn that fills it does have change: So with BTC, it's over allocating for the order, which has the nice effect of not over paying fees on the swap contract. I'm wondering if we want the split tx to make an output that is buffered extra like we see above with BTC (but not so extreme) so that the contract can have change and you don't have to over pay fees. |
|
Got some conflicts with the wireBytes stuff in now. Do you think it's worth investigating the over/under allocation issues now (currently over for BTC, correct but possibly better off higher for DCR)? It all seems to be working if not optimally. |
|
I think I see the over-allocation issue. It's how we're using |
|
Since you're hitting the over-allocation issue for quote asset funding in #594, do you have anything else for this PR? I think we could merge and tweak the issue of high fees from dust outputs with well sized outpoints in a follow up. |
|
Good to go. |
|
Going in. Note to all: the new feature is selectable in the wallet config form. However, there is a known issue with quote asset order (over)funding getting resolved in #594 (issue existed before this PR). |
Creates a "split transaction" to pre-size inputs, with some minimum reasonable consideration for negative net effects. The split transaction is sent during a call to
FundOrderif the user has specified such in their wallet configuration'stxsplitvalue.Resolves #340