Decide which coin selection solution to use based on waste metric (wallet)

https://github.com/bitcoin/bitcoin/pull/22009

Host: glozow  -  PR author: achow101

The PR branch HEAD was 32748da0f4 at the time of this review club meeting.

Notes

  • Coin Selection refers to the process of picking UTXOs (or coins) from the wallet’s UTXO pool to fund a transaction. It is a complex problem that involves minimizing short term and long term fees, working with non-guaranteed finality of payments, and avoiding privacy leaks. We have covered coin selection in previous review clubs: #17331, #17526, and #18418.

  • The Bitcoin Core wallet currently implements two coin selection algorithms.

    • KnapsackSolver is Bitcoin Core’s legacy coin selector that reduces the problem to Subset Sum and attempts to solve it through 1000 rounds of stochastic approximation. As long as the wallet has enough funds to cover the transaction, KnapsackSolver always finds a solution. It can overshoot, but the wallet just creates a change output to redeem the excess.

    • SelectCoinsBnB uses a Branch and Bound algorithm to explore a bounded search tree of potential solutions, scoring them with a metric called “waste.” Notably, the Branch and Bound algorithm looks for an exact solution and never produces a change output. As such, it’s possible for SelectCoinsBnB to fail even though the wallet has sufficient funds.

    Other coin selection algorithms have also been proposed, such as Single Random Draw in PR #17526.

  • The current behavior in AttemptSelection() unconditionally prefers the Branch and Bound solution, and only attempts to use KnapsackSolver if SelectCoinsBnB fails. PR #22009 implements a GetSelectionWaste() function and changes AttemptSelection() to try both solvers and pick the solution with lower waste, breaking ties by preferring a greater number of inputs.

  • Waste is measured in satoshis and includes the cost of creating change, the excess selection amount, and cost of spending inputs now as opposed to sometime in the future (when we expect to be able to consolidate inputs).

    • Cost of change includes the fees paid on this transactions’ change output plus the fees that will need to be paid to spend it later. If there is no change output, the cost is 0.

    • Excess selection amount refers to the difference between the sum of selected inputs and the amount we need to pay (the sum of output values and fees). There shouldn’t be any excess if there is a change output.

    • Cost of spending inputs now is the fee difference between spending our selected inputs at the current feerate and spending them later at the “long term feerate.” This helps us implement a long term fee-minimization strategy by spending fewer inputs in high feerate times and consolidating during low feerate times.

  • PR #22009 also sets the default long term feerate to 10 sats/vbyte, and creates a configuration option, -consolidatefeerate. The long term feerate represents the feerate at which we would be happy to consolidate UTXOs in transactions.

Questions

  1. Did you review the PR? Concept ACK, approach ACK, tested ACK, or NACK?

  2. Without looking at the waste calculation function, what properties would you consider when comparing different coin selection solutions? How might you quantify them?

  3. What is the waste calculation equation? How can we verify that the implementation in GetSelectionWaste() is correct?

  4. In what scenario would a coin selection solution have waste == 0?

  5. Can a coin selection solution have waste < 0? How?

  6. What does the [[nodiscard]] here attribute do?

  7. How did you review the scripted-diff commit? (You did review it, right???)

  8. What do you think of the 10 sat/vbyte consolidation feerate? What effect does this have on our waste calculation method?

  9. How does using m_consolidate_feerate instead of the 1008-block feerate estimate change our wallet’s coin selection behavior?

Meeting Log

  117:00 <glozow> #startmeeting
  217:00 <emzy> hi
  317:00 <glozow> Welcome to PR Review Club, everybody! Feel free to say hi, and let us know if it's your first time :)
  417:00 <benthecarman> hi
  517:00 <svav> Hi
  617:00 <theStack> hi
  717:00 <jnewbery> hi!
  817:00 <lightlike> hi
  917:00 <schmidty> hi
 1017:00 <notmandatory> hi
 1117:00 <glozow> today we're going to Decide which coin selection solution to use based on waste metric: https://github.com/bitcoin/bitcoin/pull/22009
 1217:00 <larryruane> hi
 1317:01 <glozow> notes are here: https://bitcoincore.reviews/22009
 1417:01 <glozow> If you have any questions at any point in time, please ask!
 1517:01 <raj> Hi..
 1617:01 <glozow> we've covered coin selection a few other times, so if you love coin selection as much as i do, you might also be interested in https://bitcoincore.reviews/17331, https://bitcoincore.reviews/17526
 1717:02 <glozow> Did anyone get a chance to review the PR or look at the notes? y/n
 1817:02 <benthecarman> y
 1917:02 <lightlike> y
 2017:02 <raj> y
 2117:02 <larryruane> only a little
 2217:02 <Azorcode> Hello everyone
 2317:02 <glozow> nice! :D
 2417:03 <theStack> 0.5y
 2517:03 <emzy> n (just read the notes)
 2617:03 <svav> n
 2717:03 <notmandatory> n
 2817:03 <chunkblob> also just read notes
 2917:03 <b10c> hi
 3017:03 <glozow> First question (good for those who didn't review the PR as well): What properties would you consider when comparing different coin selection solutions? How might you quantify them?
 3117:04 <notmandatory> transaction size
 3217:04 <theStack> first and foremost, minimizing fees, both short and long-term
 3317:05 <glozow> theStack: notmandatory: great answers
 3417:05 <svav> How much waste
 3517:05 <larryruane> not creating "dust" outputs?
 3617:05 <benthecarman> when to conslidate and when to conserve utxos
 3717:05 <glozow> larryruane: yes, absolutely!
 3817:06 <glozow> and for those who did review the PR, What is the waste calculation equation?
 3917:06 <lightlike> psychologically, minimizing the ratio of fees to total amount spent (even if it makes little sense on a technical level).
 4017:07 <glozow> lightlike: that's an interesting one. people are sometimes surprised by how fees scale in bitcoin - what's scarce to us isn't liquidity but block space, so the fees scale with the size of the transaction rather than the amount being transacted
 4117:07 <raj> waste = sum(current fee - long term fee) + Cost of spend/Excess paid in fees.
 4217:08 <benthecarman> (change_cost ==0 ? excess: change_cost )+ inputs * (effective_feerate - long_term_feerate)
 4317:08 <larryruane> I learned this from the notes, but fascinating to think about how there may be a benefit to NOT spending a particular output now (assuming fees are currently high), given that we may be able to consolidate it later when fees are low
 4417:08 <raj> Its seems to me like the first part can be thought of as "Consolidation Factor" and the second is "Money burned in the process" so kind of a "Cost".
 4517:08 <murch1> hi, yes
 4617:09 <sipa> glozow: privacy (avoiding merging and/or avoiding spending reused, to the extent possible) is another criterion for coin selection i think, but a hard to quanify one
 4717:09 <sipa> i summoned a murch1 here
 4817:09 <glozow> sipa: indeed. I would classify "not producing a change output" as slight win for privacy, and it would be interesting to see that quantified in a waste metric
 4917:10 <larryruane> sipa: is spending reuse the same as address reuse?
 5017:10 <murchandamus> glozow: Not only a win for privacy, but also a reduction of current and overall fees
 5117:10 <glozow> larryruane: raj: yeah, i particularly liked how the waste metric captures the "feerates now vs when we'd want to consolidate" part
 5217:11 <glozow> murchandamus: yes, of course
 5317:11 <murchandamus> sorry, just catching up on previous convo
 5417:11 <sipa> larryruane: i'd generally call "address reuse" the act of giving out the same address multiple times and/or peforming multiple (expected) payments to one
 5517:11 <murchandamus> I see that this has been mentioned ':-)
 5617:12 <glozow> raj: benthecarman: đź‘Ś, would you be able to break that down into english for us? :)
 5717:12 <larryruane> sipa: thanks, i was just wondering if "spending reuse" is a different concept (which I haven't heard of)
 5817:13 <sipa> larryruane: say someone sends you a ton of dust to an address you've spent from already
 5917:13 <sipa> perhaps it's worth avoiding spending that dust, beyond the normal level that would otherwise be implied by fee minimization and waste metric
 6017:13 <glozow> people can send u money without your consent?!!?
 6117:13 <murchandamus> larryruane: Bitcoin Core wallet goes out of its way to spend UTXOs associated with the same scriptPubKey together in one transaction so that there will not be multiple txns associated with the same scriptPubKey
 6217:13 <glozow> even when ur offline???
 6317:14 <glozow> ok so back to the waste metric, can anyone tell me what "excess" is?
 6417:14 <theStack> glozow: :D
 6517:14 <emzy> glozow: hehe
 6617:14 <murchandamus> glozow: No, as the seeress Francis has established, you cannot receive while offline. Duh.
 6717:14 <raj> glozow, I think maybe in this way "Waste = Opportunity Cost of waiting + Cost of Creation". Cost of Creation is always positive, while "Opportunity Cost of waiting" can be negative too..
 6817:15 <raj> If current_fee < Long_term_fee , the "Opportunity Cost of waiting" is negative.. So we should not wait and do it now..
 6917:15 <raj> Not sure if it makes sense totally though.
 7017:15 <glozow> raj: yes, i agree with that breakdown. cost of creation being the excess or change cost
 7117:16 <lightlike> "excess" is if we don't make a change output and instead add the difference to the fees.
 7217:16 <theStack> excess = input_values - output_values - fees_needed
 7317:16 <glozow> lightlike: correcto
 7417:16 <glozow> and what is cost of change?
 7517:16 <murchandamus> right: since creating change costs money, we allow for a small overshoot that we drop to fees instead of creating change
 7617:16 <benthecarman> how much fees we are paying to create a change output
 7717:17 <murchandamus> glozow: Usually either a paradigm shift or a revolution
 7817:17 <glozow> benthecarman: just to create? :)
 7917:17 <raj> cost_of_change = Cost to "spend" the change? Or to "create" the change?
 8017:17 <benthecarman> and spend in the future
 8117:17 <benthecarman> change_cost = effective_feerate * change_output_size + long_term_feerate * change_spend_size
 8217:17 <glozow> benthecarman: right, exactly!
 8317:17 <murchandamus> glozow: the cost of creating the change at the current feerate, and the cost of later spending that UTXO
 8417:17 <raj> benthecarman, Ah thanks..
 8517:18 <larryruane> would we somehow be able to capture the GOOD that a slight increase in fees does (in the case that we don't want to create a change output), in getting the tx mined more quickly? Lots of angles to all this!
 8617:18 <glozow> so does it make sense to have both excess and cost of change be greater than 0?
 8717:18 <benthecarman> No, if you have a change output than your excess should be 0
 8817:18 <murchandamus> larryruane: Well, assuming that the feerate estimate was good, it's just an overpayment, but maybe the next block is a bit slow...
 8917:18 <glozow> larryruane: we set the feerate ahead of time
 9017:18 <murchandamus> Well, it's hard to calculate
 9117:19 <glozow> benthecarman: right, exactly
 9217:19 <glozow> In what scenario would a coin selection solution have waste == 0?
 9317:19 <murchandamus> I can think of at least two :)
 9417:19 <glozow> or should i say, scenarios - there are multiple ways this is possible of course
 9517:20 <benthecarman> if you have a change output and long term fee rate == fee rate, or if excess = 0 and long term fee rate == fee rate
 9617:20 <glozow> murchandamus haha jinx
 9717:20 <murchandamus> benthecarman: No, the change output cost would still increase the waste score
 9817:20 <glozow> benthecarman: yes to the second example
 9917:21 <glozow> i.e. the stars aligned and the BnB solver produced a perfect solution, AND the effective feerate == long term feerate
10017:21 <benthecarman> oh right
10117:22 <murchandamus> If the feerate is below the long term feerate and the inputs' score matches excess or cost of change you can also hit a 0
10217:22 <glozow> or, it produced an imperfect solution, but subtract fees from outputs was on, and the excess was absorbed nicely...
10317:22 <murchandamus> *negatively matches
10417:22 <theStack> if we get a perfect solution via the BnB solver, both the cost of change and excess selection amount are always zero (since there is no change output). did i get that right?
10517:22 <glozow> murchandamus: right, if cost to spend now is negative and equal to the excess or cost of change
10617:22 <glozow> then they'll balance each other out
10717:22 <murchandamus> theStack: Yes
10817:23 <murchandamus> glozow: Nit: not the cost to spend, but the waste score
10917:23 <murchandamus> You're still paying for the inputs ;)
11017:23 <lightlike> glozow: i agree - so the "only" https://github.com/bitcoin/bitcoin/blob/5e3380b9f59481fc18e05b9d651c3c733abe4053/src/wallet/test/coinselector_tests.cpp#L727 is not correct, right?
11117:23 <benthecarman> lightlike: haha looks like it
11217:23 <murchandamus> lightlike: good catch
11317:23 <glozow> murchandamus: i'm using "waste" as defined in GetSelectionWaste(), so it'd be confusing to call cost to spend waste scorfe?
11417:24 <glozow> lightlike: indeed! haha
11517:24 * murchandamus gets out his pitchfork starts looking for achow101
11617:24 <glozow> How might we verify that `GetSelectionWaste` is implemented as specified?
11717:24 <glozow> (how did you review it?)
11817:25 <benthecarman> Tests!
11917:25 <larryruane> unit tests with very specific inputs? (I didn't review it)
12017:25 <raj> Printed the test results and matched by hand calculations..
12117:26 <glozow> benthecarman: larryruane: raj: good answers
12217:26 <murchandamus> glozow: I was trying to differentiate between the actual cost of spending UTXOs and how they're scored by the waste metric. Not sure where you see "cost to spend".
12317:27 <glozow> as u can see, my method is to host a pr review club (u can too! contact jnewbery)
12417:27 <glozow> we kind of already covered this, but: Can a coin selection solution have waste < 0? How?
12517:27 <murchandamus> Indubitably!
12617:27 * murchandamus leaves how to someone else
12717:28 <benthecarman> if fee_rate < long_term_fee_rate
12817:28 <lightlike> yep, if current ees are low enough compared to the long-term fee rate to overcome the excess or cost of change
12917:28 <larryruane> murchandamus: never use a big word when a dimunitive one would do
13017:28 <benthecarman> * and cost of change/excess doesn't bring it over
13117:28 <raj> glozow, No Excess && No Chanage && Fee < Long term fee?
13217:28 <glozow> yep yep!
13317:29 <murchandamus> larryruane: "diminutive"? :p
13417:29 <glozow> ok i always like to do some C++ questions: What does the [[nodiscard]] do here? https://github.com/bitcoin/bitcoin/blob/21566d03d1131f919df65efae7212c18f657f0fd/src/wallet/coinselection.h#L182
13517:29 <larryruane> murchandamus: đź‘Ť
13617:29 <larryruane> ah, that's so the caller can't ignore the function return value! (without a warning at least)
13717:29 <glozow> hint: https://en.cppreference.com/w/cpp/language/attributes/nodiscard
13817:29 <theStack> it's for telling the compiler that we'd like to get noticed if we don't use the return value
13917:30 <murchandamus> Oooh, glozow I have another question, may I?
14017:30 <glozow> larryruane: theStack: yes! :D
14117:30 <benthecarman> your return value says notice me senpai
14217:30 <glozow> murchandamus: yes go ahead
14317:30 <larryruane> however you can cast the return to void .. what's the best way in c++? I'm used to c, where it's just `(void)`
14417:30 <raj> benthecarman, haha.. They should put this in cpprefernce..
14517:30 <murchandamus> When actual feerate is equal to long term feerate, how does the number and type of inputs impact the waste score? What does that mean for the input count vs excess optimization?
14617:31 <benthecarman> ooh good question
14717:31 <theStack> larryruane: according to the cppreference link glozow shared it seems to work the same way in C++... cast to void
14817:31 <glozow> ooooh nice one. i also forgot to ask "how do we break ties when waste is equal?"
14917:31 <sipa> https://stackoverflow.com/questions/47104328/is-it-possible-to-ignore-nodiscard-in-a-special-case
15017:31 <raj> there goes my tomorrow morning.. :D
15117:31 <larryruane> theStack: I was just wondering the preferred syntax to do that
15217:32 <benthecarman> It shouldn't impact the waste score, so we should use results that have less total fees for tie breaks?
15317:32 <theStack> larryruane: ah sorry, i misinterpreted your question. you mean like if there is something like "static_const<void>" or similar
15417:33 <larryruane> theStack: yes
15517:33 <murchandamus> benthecarman: Actually, I think it prefers the solution that uses more inputs
15617:33 <glozow> benthecarman: right, the number of inputs wouldn't impact the waste score
15717:33 <benthecarman> murchandamus: why is that?
15817:33 <murchandamus> However, if the waste score is the same, how do the fees compare?
15917:34 <larryruane> murchandamus: is that so we reduce the size of the UTXO set? to help the community?
16017:34 <murchandamus> Yes, we err on being more consolidatory
16117:34 <glozow> if the waste score is the same, you prefer the one that has more inputs, which you are indeed paying more fees on
16217:34 <schmidty> Since waste was a metric introduced by BnB and this PR introduces a new GetSelectionWaste method, are there two different types of "waste" now? If the two types of waste are the same, should BnB use the new GetSelectionWaste for calculations?
16317:35 <benthecarman> i guess that makes sense, if your long_term_fee_rate is what you expect to pay, then you would want to conslidate then
16417:35 <glozow> schmidty: good question
16517:35 <murchandamus> schmidty: It's the same waste metric, it has just been generalized to apply to all sorts of selection results
16617:36 <benthecarman> the bnb implementation wasn't touched in this PR to use `GetSelectionWaste`, would that be a good follow up PR to reduce code duplication
16717:36 <schmidty> Should BnB use that generalized method internally? murchandamus
16817:36 <schmidty> benthecarman: yes that’s what Im getting at.
16917:36 <murchandamus> glozow: I need to think more about it, but from the top of my gut I would say that when the waste score is equal, two changeless input set candidates would cost the same fees
17017:37 <murchandamus> It's a bit more complicated when comparing a changeless solution with one that produces change, but there it would cause the changeless to be preferred, I think
17117:37 <glozow> schmidty: indeed. it would be bad for those calculations to diverge
17217:37 <benthecarman> murchandamus: if you were spending different output types they wouldnt be
17317:37 <murchandamus> schmidty: If it does not yet, it definitely should
17417:38 <glozow> murchandamus: when you have long term feerate == effective feerate, two solutions can pick a different number of inputs and end up with the same excess, no?
17517:38 <glozow> or same change cost
17617:38 <murchandamus> glozow: True in the case of being right on the boundary
17717:40 <murchandamus> benthecarman: You sure? ;)
17817:40 <benthecarman> now im not lol
17917:41 <glozow> can anyone think of other things that could be added to the waste measurement?
18017:41 <glozow> feel free to throw out ideas
18117:41 <benthecarman> privacy, hard to quantify though
18217:41 <glozow> for example, I wonder if we would want to weight cost of change vs excess differently, given that one has a change output and one doesn't
18317:41 <murchandamus> benthecarman: Let's take it offline, it might take a while to pick apart
18417:42 <murchandamus> glozow: What do you propose concretely? :)
18517:42 <lightlike> i wonder why the long-term fee default value was changed to a fixed value. would the whole thing work less well with a dynamic estimate based on the last X blocks, as was in place before?
18617:42 <glozow> e.g. if you scaled the cost of change by 1.1
18717:43 <murchandamus> Would be wonderful if we had some heuristic to quantify privacy
18817:43 <glozow> lightlike: i thought that was interesting as well, though i imagine that the long term fee estimate is usually about the same
18917:43 <murchandamus> Hard, though, I think
19017:43 <notmandatory> as I think sipa implied not spending all utxos to the same script could be a negative (in privacy terms)
19117:44 <murchandamus> lightlike: the problem was that the 1008 block target is basically always 1 sat/vB if the mempool has cleared once in the last week
19217:44 <glozow> mm, i think we already have a countermeasure to that type of dust attack
19317:44 <murchandamus> So it would never actually switch between consolidatory and thrifty mode
19417:45 <glozow> (see https://bitcoincore.reviews/18418)
19517:45 <murchandamus> glozow: But the cost of change is already fairly dissuading since it counts both the creation and an assumed long term cost
19617:46 <murchandamus> Although, yeah, avoiding change could definitely be encouraged ;)
19717:46 <notmandatory> glozow: +1 thanks
19817:46 <raj> murchandamus, when you say the selction algo switches mode (consolidate or reduce fee) is that simple choice between BnB and KnapSack or something more going on?
19917:47 <benthecarman> maybe something you'd want to incorporate into waste is coins days destroyed, if you only want to spend recently received coins
20017:48 <glozow> raj: murch means switching into "we want to spend more inputs to consolidate them" mode
20117:48 <murchandamus> raj: It doesn't switch the preferred algorithm but it switches whether it prefers the solution with more inputs or fewer inputs (via the waste metric)
20217:48 <glozow> benthecarman: that's interesting, like you always prefer to spend more recently received ones?
20317:48 <raj> glozow, Ah.. And can you point me where exactly this switch logic happening?
20417:49 <murchandamus> benthecarman: Why'd you want to do that?
20517:49 <benthecarman> yeah maybe for privacy reasons or something
20617:49 <glozow> raj: it's in the waste metric calculation, it depends on what the effective feerate is
20717:49 <murchandamus> Wouldn't that mean that fewer funds are moved much more often?
20817:49 <glozow> when effective feerate < long term feerate, the switch happens
20917:49 <murchandamus> I.e. seems like privacy detriment more than a boon
21017:49 <benthecarman> I'm not too sure, just throwing idea out for other metrics to add to waste
21117:49 <glozow> you could also use coin control to manually pick the recent coins you want to use
21217:50 <benthecarman> yeah I guess you would spend lots of the same funds often
21317:50 <murchandamus> benthecarman: Sorry, brainstorm on!
21417:51 <benthecarman> Another thing is maybe change output size, maybe you don't want to doxx your 50 bitcoin output when buying coffee
21517:51 <benthecarman> change output value*
21617:51 <notmandatory> murchandamus and benthecarman: maybe preferring oldest utxos is better, at least makes pruned nodes smaller?
21717:51 <murchandamus> raj: Since inputs get a negative score below the long term feerate, a candidate input set with more input size would be preferred over one with less input size at low feerates, whereas the opposite is true at higher feerates. This shifts some of the UTXO consumption to lower feerates overall saving cost
21817:52 <raj> murchandamus, Oh i see. So its kinda happens implicitly?
21917:52 <murchandamus> raj: yes!
22017:52 <larryruane> notmandatory: I don't think pruning is related to UTXO db
22117:53 <murchandamus> raj: Well, BnB does it during it's search also, so it'll tend to find a waste score optimized solution among the possible ones
22217:53 <glozow> benthecarman: kind of along those lines, maybe we can measure privacy based on the difference between the payment amount and change output amount
22317:53 <glozow> one aspect of privacy i mean
22417:53 <glozow> (just throwing out random ideas)
22517:54 <raj> murchandamus, So would this be correct to say, just having a waste metric is not enough to ensure this tendency of the wallet, it also has to be used correctly?
22617:54 <murchandamus> but we only pick from two results, so it's not like we build an actual consolidation transaction at low feerates and a minimized tx at high feerates. It's just a small bias.
22717:54 <glozow> murchandamus: do you think we could use waste metric in place of the sequential calls to AttemptSelection()?
22817:55 <glozow> well we could, but i mean to ask if you think it's a good idea*
22917:55 <raj> murchandamus, got it.. thanks..
23017:55 <lightlike> if everyone in the world used the bitcoin core algorithm, would there be some reverting-to-the-mean effect stabilizing fees around 10sats/vbyte? if the current fee rate is below this, utxos are consolidated, leading to larger transactions and less block space, driving fees back up
23117:55 <murchandamus> oh, since knapsack was upgraded to use effective feerates, it should (almost) always find a solution if one is possible.
23217:56 <murchandamus> So "attempt selection" should only fail if there are insufficient funds
23317:56 <glozow> I wanted to ask this question from the notes: How did you review the scripted-diff commit? (You did review it, right???)
23417:57 <murchandamus> lightlike: Good question. I have been thinking about that too. I think that could happen if there were generally more continuous blockspace demand
23517:57 <glozow> murchandamus: right, but i'm asking about replacing it, so instead of only trying coins with 1 confirmation when 6+ fails, you try both and pick the one with less waste
23617:57 <raj> glozow, I just looked.. And didn't knew what else to do.. Wanna know how to review them quickly..
23717:57 <murchandamus> currently, we have a lot of gaps where the mempool actually empties out completely
23817:57 <benthecarman> raj: there is a script you can run in the commit message
23917:57 <larryruane> glozow: I ran `test/lint/commit-script-check.sh 935b3ddf72aa390087684e03166c707f5b173434~..935b3ddf72aa390087684e03166c707f5b173434` (but I know CI does that anyway), but to review, you study the script!
24017:58 <murchandamus> glozow: Oh, I see, I guess one could
24117:58 <glozow> larryruane: good yes
24217:58 <glozow> CI will verify the script is correct for you, but you should review the script
24317:58 <murchandamus> I thought "AttemptSelection" was the thing that looped Knapsack if the fees were insufficient after finding a solutino
24417:59 <raj> benthecarman, ok in that way I can repro the changes? But then I have to manually see if all required changes are covered?
24517:59 <theStack> would it make sense to support multiple change outputs in the future, just for the sake of confusing on-chain analysis and increasing privacy?
24617:59 <larryruane> here's an hourly update on the fees according to various confirmation times: https://twitter.com/bitcoin_fees
24718:00 <murchandamus> glozow: I guess that would basically compound to just not preferring 6 confs especially
24818:00 <glozow> so for instance, if the script was replacing `filter_standard` with `filter_confirmed` that would be wrong, even though the linter passed
24918:00 <murchandamus> theStack: There are reasons to create multiple outputs occasionally, yes.
25018:00 <larryruane> theStack: interesting idea! Also if somehow you know that in the future you'll need inputs with a specific amount, maybe make a change output with that exact amount?
25118:01 <glozow> uhoh it's time already
25218:01 <glozow> #endmeeting