Add tracepoints and algorithm information to coin selection (wallet)

Host: glozow  -  PR author: achow101


  • User-Space, Statically Defined Tracing (USDT) allows observability into runtime internals at statically defined tracepoints. We have discussed USDTs at previous PR Review Club meetings, #22006 and #23724.

  • Coin Selection is the process of selecting UTXOs (“coins”) from a wallet’s UTXO pool in order to fund a transaction’s payment(s). We have discussed coin selection at preview PR Review Club meetings, including #22009, #17526 and #17331.

  • PR #24644 adds tracepoints to the wallet’s coin selection code.


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

  2. What tracepoints does this PR add, and what information do they collect?

  3. Why might we be interested in which algorithm was used and what the waste score is? How might we use this information to improve coin selection?

  4. Instead of instrumenting the coin selection code with tracepoints, why don’t we just add logs?

  5. What is a C-style string and why do the tracepoints pass this type of string?

  6. What’s the difference between the two calls to CreateTransactionInternal? What does it mean to Avoid Partial Spends?

  7. Under what circumstances is the coin selection algorithm labeled as “manual”?

Meeting Log

  110:00 <glozow> #startmeeting
  210:00 <glozow> hi everyone!
  310:00 <svav> Hi
  410:00 <a1ph4byte> Hello!
  510:00 <emzy> hi
  610:00 <Frank0> hi
  710:00 <theStack> hi!
  810:00 <glozow> Welcome to PR Review Club! Anyone here for the first time?
  910:00 <sipa> hi
 1010:00 <lightlike> hi
 1110:00 <b10c> hi
 1210:01 <glozow> we're looking at #24644, "Add tracepoints and algorithm information to coin selection" today
 1310:01 <Frank0> yes me
 1410:01 <b_1o1> hi all
 1510:01 <a1ph4byte> First Timer here
 1610:01 <glozow> Notes in the usual place:
 1710:01 <jacobpfickes> Hi all!
 1810:01 <ccdle12> hi
 1910:01 <Frank0> first time
 2010:01 <schmidty> hi
 2110:01 <glozow> Awesome, welcome Frank0 and a1ph4byte!
 2210:01 <effexzi> Hi every1
 2310:01 <svav> To the new people, where did you here about this meeting if you don't mind sharing? Thanks
 2410:01 <glozow> Did anybody get a chance to review the PR or look at the notes? How about a y/n
 2510:02 <a1ph4byte> browsing the bitcon-core contributor notes
 2610:02 <Frank0> chain code labs bitcoin seminar
 2710:02 <emzy> y (a little)
 2810:02 <a1ph4byte> n
 2910:02 <svav> y looked at the notes
 3010:02 <b10c> y
 3110:02 <b_1o1> y
 3210:02 <svav> Thanks Frank0
 3310:02 <larryruane> hi
 3410:03 <theStack> n
 3510:03 <glozow> could somebody summarize for us what this PR does?
 3610:04 <svav> It adds tracepoints into the wallet's coin selection code, so we can better understand how it's performing
 3710:04 <glozow> svav: perfect, thank you!
 3810:04 <svav> ... and how "good" coin selection is
 3910:05 <glozow> And can somebody quickly summarize for us what tracepoints are?
 4010:05 <larryruane> a way of getting access to internal state of a running bitcoind for debugging or general understanding
 4110:06 <larryruane> it's sort of like logging (where you can enable particular categories) but less intrusive (?)
 4210:06 <svav> Once a tracepoint is reached, it can pass data about process internals to a userspace script for further processing. This is great for observability and allows for debugging, testing, and monitoring.
 4310:06 <glozow> larryruane: right! And what's special about these tracepoints in particular? Is there a difference between tracepoints and logs?
 4410:07 <larryruane> when you say these, do you mean coin selection tracepoints?
 4510:07 <glozow> svav: đź‘Ť
 4610:07 <glozow> I mean, USDTs versus other types of telemetry
 4710:07 <svav> A tracepoint is triggered by particular code activation
 4810:07 <svav> So a tracepoint shows what code is being called, unlike a log
 4910:08 <a1ph4byte> May I ask, what is meant by "coin selection"
 5010:08 <larryruane> The other difference I think of with tracepoints is that, with logging, you can later process the log file (to summarize what's in it), but there could be a huge amount of disk space consumed ... with tracepoints, you can sort of "compress" the information on the fly
 5110:08 <glozow> for anyone that's unfamiliar with USDTs, is a good place to start
 5210:08 <sipa> svav: What do you mean by "what code is being called" ?
 5310:09 <b10c> logging is primarily a interface for humans, tracepoints are a interface for machines
 5410:09 <svav> a1ph4byte Coin Selection - The process of selecting UTXOs (“coins”) from a wallet’s UTXO pool in order to fund a transaction’s payment(s).
 5510:10 <b10c> we can still parse log messages, but the contents might change over time and we might end up e.g. printing a hash as hex and then parsing it back in which isn't efficient
 5610:11 <Murch> a1ph4byte: A general term for the strategies and algorithms used to pick the inputs for transactions
 5710:11 <sipa> I think another important difference is that logging is an actual action, where tracepoints are just hooks that an external process can plug into. A tracepoint on itself does nothing unless something uses it.
 5810:11 <glozow> thanks sipa and b10c!
 5910:11 <larryruane> i have a really basic question, when a thread hits an active tracepoint, does the thread suspend until the data is received by the tracing script? Or is there a memory queue of tracing events so the thread can continue asynchronously?
 6010:12 <PaperSword> A tracepoint can still execute functions within the TRACEx call.
 6110:12 <sipa> stijnbtc: Note that people outside of matrix can't see your emoji response.
 6210:12 <stijnbtc[m]1> Ah good to know!
 6310:12 <svav> sipa What I mean is a tracepoint can provide specific information about what code is doing ... at specific points in the code ...
 6410:13 <glozow> Feel free to continue a background thread for general USDT questions. I'll also start with the questions about the PR.
 6510:13 <glozow> What 4 tracepoints does this PR add, and what information do they collect?
 6610:13 <PaperSword> No suspension I believe, data goes into the ringbuffer where it can be over written if not read right awway.
 6710:13 <PaperSword> sorry
 6810:15 <svav> For reference, I think SystemTap is being used to provide the tracepoints
 6910:15 <pop> For reference, here is the doc/ to see a generalized tracepoint diagram:
 7010:16 <b10c> larryruane: in assembly, the tracepoint is a literal NOP (no operation). If we tell the kernel to hook into the tracepoint, it executes a small eBPF bytecode program e.g. adding data to a eBPF map where it can be read asynchronously from a userspace program
 7110:16 <b10c> It doesn't suspend
 7210:16 <svav> So this PR adds 4 new tracepoints:
 7310:16 <svav> After SelectCoins returns in order to observe the SelectionResult
 7410:16 <svav> After the first CreateTransactionInternal to observe the created transaction
 7510:16 <svav> Prior to the second CreateTransactionInternal to notify that the optimistic avoid partial spends selection is occurring
 7610:16 <svav> After the second CreateTransactionInternal to observe the created transaction and inform which solution is being used.
 7710:17 <glozow> svav: well prepared :)
 7810:18 <PaperSword> coin_selection:selected_coins collects 1. Wallet name as `pointer to C-style string`
 7910:18 <PaperSword> 2. Coin selection algorithm name as `pointer to C-style string`
 8010:18 <PaperSword> 3. Selection target value as `int64`
 8110:18 <PaperSword> 4. Calculated waste metric of the solution as `int64`
 8210:18 <PaperSword> 5. Total value of the selected inputs as `int64`
 8310:18 <Murch> glozow: The tracepoints collect information on the algorithms that produced the input selection, the total amount selected, the waste score, some details on fees, change output position, and whether the solution is `avoid_partial_unspents` compliant
 8410:18 <sipa> b10c: But execution of bitcoind is suspect while the kernel executes the eBPF program - it's the reading out of the results that is done asynchronously?
 8510:18 <sipa> s/suspect/suspended/
 8610:18 <sipa> (I've never actually used eBPF/USDT)
 8710:18 <glozow> Murch: PaperSword: nice
 8810:19 <glozow> so svav told us what the 4 tracepoints are, and Murch and PaperSword told us what information is being collected
 8910:19 <glozow> Why might we be interested in the algorithm and waste score? How might we use this information to improve coin selection?
 9010:19 <larryruane> b10c: so the NOP is replaced at runtime (after the program is loaded in memory)? Sort of the way breakpoints work?
 9110:19 <b10c> sipa: yes, while the eBPF program runs bitcoind is suspended. So hooking into tracepoints in tight loops might affect performance
 9210:20 <PaperSword> There is more info collected that was just the the args passed for 1/4 traces
 9310:20 <sipa> Got it.
 9410:20 <pop> Improving the coin selection algorithm has obvious downstream benefits for all wallets that are based on/rely on the bitcoind wallet.
 9510:20 <glozow> PaperSword: right, that's the info for `selected_coins` tracepoint yes?
 9610:20 <PaperSword> Trace is only optimized to just a NOP if compiled without ePBF support?
 9710:21 <PaperSword> yes that is correct.
 9810:21 <pop> Is it relevant to ask how coin selection algorithms were developed prior to the proposal of these 4 tracepoints?
 9910:21 <glozow> pop: right
10010:22 <Murch> While it's easy to evaluate a coin selection algorithm on a single situation (UTXO pool and selection target), the overall problem we're interested in is the emergent behavior of various algorithms over longer scenarios of payment sequences and feerates.
10110:22 <b10c> larryruane: yes, I think of it similar to breakpoints in a debugger on the NOP, the positions of these NOPs are written into a ELF note of the bitcoind binary
10210:22 <theStack> PaperSword: i'd assume that if we compile without eBPF support, there are not even NOPs, because the TRACE... defines are replaced by empty strings
10310:23 <Murch> The tracepoints allow us to observe how the UTXO pool evolves over time and to assess the overall fee expenditures as well as the individual outcomes of each payment
10410:23 <glozow> Murch: yes thank you.
10510:23 <achow101> pop: the tracepoints let us do simulations. prior to tracepoints, these simulations required an aditional patch which adds a couple of globals and RPCs that let us measure some things. but these could not be upstreamed so had to be maintained separately
10610:23 <pop> Murch: So without net tracepoints to track coinselection metrics over longer periods and map the interactions between multiple algorithms, there is no way to evaluate the emergent behavior of coin selection?
10710:24 <glozow> I also think it's a good way to evaluate the accuracy of our waste metric
10810:24 <sipa> pop: Sure there is, but you couldn't do it with an unmodified bitcoind. Tracepoints provide a way for profiling software to hook into bitcoind, unmodified.
10910:24 <b10c> PaperSword: when compiled without tracing support, there's nothing tracing related in the code. The TRACEx makros are empty if tracing is disabled
11010:25 <PaperSword> per "even if the tracepoint is not used. For example, avoid serialization and parsing."
11110:25 <Murch> pop: Previously we had either created separate simulation frameworks or modified a copy of Bitcoin Core to add the corresponding logging. Having the tracepoints allows us to keep the log generation and processing in a separate project which makes it easier to apply the tracing to many different states of the codebase
11210:26 <PaperSword> *"Although the tracepoint itself only has overhead when enabled, the code to compute arguments is always run"
11310:26 <glozow> right, with tracepoints we get the win-win of upstream support for observability + people who don't care about that won't be imapcted
11410:26 <popracepoints allows us to keep the log generation and processing in a separate project which makes it easier to apply the tracing to many different states of the codebase
11510:26 <PaperSword> *"Although the tracepoint itself only has overhead when enabled, the code to compute arguments is always run"
11610:26 <glozow> right, with tracepoints we get the win-win of upstream support for observability + people who don't care about that won't be imapcted
11710:26 <pop> sip: I see. So the pull in question consolidates patches into the main bitcoind codebase and removes the need to maintain additional code.
11810:26 <a1ph4byte> Where are the coin selection algorithms implemented? Is this apart of the bitcoin-core or is this implemented by external software apps?
11910:26 <sipa> Part of Bitcoin Core.
12010:26 <glozow> see src/wallet/coinselection.{h,cpp}
12110:26 <Murch> a1ph4byte: The coin selection algorithms are part of the Bitcoin Core codebasez
12210:26 <PaperSword> glozow: Correct, though it can lead to messy looking code because each trace takes up space. Just my opinion.
12310:27 <b10c> PaperSword: this guidance is relevant for people who run a bitcoind with tracing support, but don't hook into the tracepoints. Release builds have tracepoint support, so we assume that's the case for a majority of our users.
12410:27 <glozow> sure, though a few lines of code is a trivial cost to pay for the observability benefits
12510:27 <PaperSword> b10c: Thank you for clarifying.
12610:28 <sipa> PaperSword: By "space" you mean lines of code in the source?
12710:28 <PaperSword> glozow: I agree.
12810:28 <PaperSword> sipa: yes
12910:28 <PaperSword> I can't speak on the waste metric.
13010:29 <sipa> Ok, sure, it takes up source code space, but any alternative that doesn't have that will just not have any logging/tracing/observing of the relevant metric at all.
13110:29 <theStack> b10c: "Release builds have tracepoints support" oh that's interesting, i would have guessed that they are only useful for developers and are disabled for releases
13210:29 <glozow> for those interested, here's `AttemptSelection` which tries various algorithms:
13310:29 <larryruane> so do we ask important bitcoind users, such as exchanges, to enable tracepoints to learn about real-world behavior? (and send us results) Or is the intention that tracepoints are only for us dev types?
13410:29 <glozow> here is where the waste metric is defined:
13510:29 <PaperSword> correct me if I am wrong release builds only have trace support when built with 'depends'
13610:30 <glozow> and here are the 3 coin selection algorithms we use
13710:30 <sipa> release builds are built with depends
13810:30 <sipa> (by "release builds" we mean the binaries that are distributed on etc)
13910:30 <PaperSword> glozow: I was already able to take a look at the metric, but spent a lot of time trying to get the tests in this PR to pass on RHEL linux. I was unable to successfuly run the tests from this PR.
14010:30 <pop> Are there currently only 11 tracepoints implemented as listed in doc/
14110:31 <PaperSword> sipa: thanks
14210:31 <glozow> larryruane: yeah that would be amazing if people could collect data for us this way
14310:31 <achow101> larryruane: the intention was to use it with the simulation script that I've written
14410:31 <Murch> We also had a PR Review club on a waste metric related PR
14510:31 <PaperSword> I love tracepoints.
14610:32 <glozow> seems like achow101 and Murch have been running the simulations on transaction data collected from some donors
14710:32 <achow101> I would not really expect others to log with these tracepoints and give us the data. it does not preserve privacy
14810:32 <glozow> achow101: what about aggregate stats?
14910:33 <glozow> if a really huge enterprise wallet could tell us the distribution of algorithms used at different feerates, for example
15010:33 <b10c> theStack: It makes sense to have the tracepoints in release builds to allow people to trace their production setups. Switching binaries is often not something you want to do if your trying to debug a problem.
15110:33 <Murch> larryruane: We currently have three datasets, an online gambling service'Âż payment sequence, a merchant's inbound payments, and another services payments. Still looking for something representative of individual users
15210:33 <glozow> although i hope enterprise wallets aren't using bitcoin core wallet
15310:34 <achow101> glozow: aggregate data could be useful
15410:34 <larryruane> some other projects (storage systems) have this "phone home" idea, but it was always a huge privacy concern ... I can understand why we can't / shouldn't do anything like that!
15510:36 <Murch> Yeah, maybe to make it clear, this is not a telemetry function, it's just for users to hook into stuff running on their own computer. Our simulation scenarios are merely lists of the incoming and outgoing amounts they've processed without additional information (and slightly fuzzified amounts for privacy)
15610:36 <pop> achow101: it's hard to imagine a dataset of transactions that wouldn't be personally identifiable, especially if those transactions have made it into blocks
15710:36 <PaperSword> Note that tracing programs have to be run as root and only support linux right now.
15810:37 <achow101> pop: it's possible to anonymize payment datasets by adding/subtracting a small random amount to each payment amount
15910:37 <PaperSword> To hook into eBPF tracepoints is quite a deliberate action.
16010:38 <pop> achow101: but wouldn't that affect the waste metric? If you are using the dataset to evaluate coin selection algorithms?
16110:38 <theStack> b10c: that makes sense
16210:39 <a1ph4byte> a more general question: what is the rationale behind developing coin selection algorithms as opposed to a simplistic FIFO model?
16310:39 <achow101> pop: with the simulation framework, we make each payment and use the tracepoints to observe what coin selection did
16410:40 <Murch> pop: it's an amount and a feerate for each payment, e.g. someone paid
16510:40 <Murch> 0.001032 â‚ż at a feerate of 0.00015817 â‚ż/kvB
16610:40 <Murch> they might tell us
16710:40 <Murch> 0.00102723,0.00015831
16810:40 <Murch> so, we don't know the txid, time, or actual values
16910:40 <theStack> could the tracepoints probably also serve as a replacement to the zmq notifications, on the long term? (don't know too much on either of the two areas)
17010:41 <achow101> a1ph4byte: we want to have our automatic coin selection behave in a smart way, e.g. reduce fees when feerates are high, consolidate more when feerates are low. a simplistic algorithm can result in unexpected or undesired behavior
17110:41 <Murch> pop: We run the data as a benchmark against different coin selection improvements to compare which perform better on the scenario. So the exact amounts aren't that important
17210:41 <glozow> a1ph4byte: you might find useful information in these notes FIFO would be expensive and leak information about the wallet, etc.
17310:41 <PaperSword> theStack: IMO this would be amazing but tracepoints have lower compatibility. Linux as root only.
17410:42 <achow101> a1ph4byte: there are also privacy considerations, and maintaining a usable utxo pool for the wallet (e.g. not producing sand (near-dust) outputs)
17510:42 <Murch> a1ph4byte: I wrote a bit about that here:
17610:42 <a1ph4byte> glozow super helpful link!
17710:42 <pop> achow101: Murch: So the important thing is to simply have data that has a close relationship with actual usage. The specific relationship between payment and feerate isn't critical at this point in coin selection algorithm development?
17810:42 <b10c> theStack: the tracepoints are currently Linux only. MacOS and Win might need ZMQ notifications too
17910:43 <achow101> pop: yes
18010:43 <theStack> PaperSword: indeed, needing to run as root seems to be quite of a drawback (though i think someone mentioned at #bitcoin-core-dev recently that laanwj managed to get them to run without root... maybe someone knows more details)
18110:43 <Murch> Right, we just want something that is representative of how people use Bitcoin to reason about whether what we're doing improves their outcome
18210:44 <theStack> b10c: good point
18310:44 <Murch> They don't even have to be the Bitcoin Core wallet
18410:44 <b10c> theStack: currently we only make data available via tracepoints that's already present in the function they are called in. that means, transactions and blocks might need additional serialization which could be "expensive"
18510:44 <glozow> It would be nice to simulate what would happen if we lowered the consolidation feerate
18610:46 <Murch> glozow: I have a branch for that
18710:46 <laanwj> theStack: PaperSword: yes, two capabilities are needed for tracepoints, full root isn't needed (on recent-ish kernels) see
18810:46 <glozow> Murch: nice
18910:46 <b10c> theStack:
19010:46 <glozow> Also might be nice to factor "remaining number of confirmed UTXOs in wallet after this transaction is created" in to waste metric
19110:46 <theStack> laanwj: b10c: thanks!
19210:47 <PaperSword> laanwj: I saw this :D Haven't had a chance to try it yet.
19310:47 <PaperSword> laanwj: thanks
19410:48 <Murch> glozow: josibake and I talked about that last week as well
19510:49 <Murch> He suggested that we might introduce additional metrics and use scores from all of them to pick the best selectionresult rather than just the wastemetric
19610:49 <glozow> endless room for improvement in coin selection
19710:49 <Murch> Two that we talked about were "reliability" and "privacy" metrics
19810:49 <glozow> Yeah, you might want a "privacy score" encapsulating whether you have a change output, how many inputs you're pulling together of what outputtypes, etc
19910:50 <glozow> but hard to quantify, i'm sure
20010:50 <Murch> E.g. spending unconfirmed inputs would reduce your reliability score, and mixing inputs with different script types reduce your privacy score
20110:50 <glozow> @ review clubbies, we have a few more questions in the notes - do we want to go through them?
20210:50 <Murch> Indeed
20310:51 <PaperSword> Yes
20410:51 <glozow> We don't have to - I think the conversation has been very educational and on topic. Just asking
20510:51 <Murch> Yeah, we got a bit sidetracked, go ahead
20610:51 <glozow> Okay cool. What is a C-style string and why do the tracepoints pass this type of string?
20710:52 <PaperSword> Null terminated string and it's passed because of the fact it's can be used in a ring buffer?
20810:53 <pop> glozow: I don't think this one was answered: 4. Instead of instrumenting the coin selection code with tracepoints, why don’t we just add logs?
20910:53 <PaperSword> Without termination in a ringbuffer specifically the ePBF program would not know when the var passed ended?
21010:53 <glozow> pop: Oh yeah, I skipped that one since we had some discussion about it in the beginning. We can go over that one too
21110:55 <PaperSword> Also without termination the user would have to pass a len arg, that would be crazy expensive given the 6/12 arg limit on trace functions
21210:55 <Murch> pop: I think I kinda did
21310:55 <pop> murch: sorry, you're right
21410:55 <glozow> PaperSword: yeah, C-strings don't know their own length so you just need to look for \0 when parsing. I don't know the answer to "why does it need to be a C-string," I assumed we have to use primitive data types or something
21510:56 <achow101> the c-style string is because the ebpf program is in C :)
21610:56 <glozow> aha there we go
21710:56 <achow101> it doesn't compile if you give it the std::string
21810:56 <Murch> "Previously we had either created separate simulation frameworks or modified a copy of Bitcoin Core to add the corresponding logging. Having the tracepoints allows us to keep the log generation and processing in a separate project which makes it easier to apply the tracing to many different states of the codebase"
21910:56 <b10c> We can't pass C++'s std::string to C
22010:56 <PaperSword> my bad,
22110:56 <glozow> are `char[]` and `char*` the same thing in C?
22210:56 <PaperSword> I was thinking about just sending a char array instead
22310:57 <PaperSword> sans termination*
22410:57 <sipa> glozow: *almost*
22510:58 <sipa> sizeof(char[]) gives the length of the array and &(char[]) returns a pointer to the first element of the array (so, itself). For all other purposes, a char[] just degenerates into a char*
22610:58 <sipa> C arrays are bad.
22710:58 <glozow> I guess in this scenario, then, they would be equivalent
22810:59 <sipa> Yes, you can't pass an array as an argument in C, for example - it degenerates into a pointer.
22910:59 <sipa> Also if you define a function that takes a char[] as argument, it's actually an argument of type char*.
23010:59 <PaperSword> sipa: correct
23111:00 <theStack> sipa: there are fixed size array parameters possible though, isn't it? like "void foo(int bla[5])"... at least i vaguely remember that i used this years ago, maybe it was non-standard though
23211:00 <sipa> theStack: Nope, that is exactly equivalent to writing "void foo(int* bla)".
23311:00 <sipa> (IIRC)
23411:00 <glozow> We're out of time, hopefully this was fun!
23511:01 <sipa> You can write it, but it's just information for the programmer.
23611:01 <glozow> #endmeeting
23711:01 <theStack> sipa: okay, so it is accepted, but the specified size doesn't have any meaning
23811:01 <sipa> (going to test that now, theStack)
23911:01 <emzy> Thank you glozow and all!
24011:01 <PaperSword> thanks
24111:01 <pop> thanks, really informative
24211:01 <svav> Thanks glozow and all!
24311:01 <b10c> thanks!
24411:01 <theStack> sipa: at least the compiler could be so nice to use it to detect an obvious out-of-bounds access at compile-time :)
24511:01 <a1ph4byte> glozow This was wildly beneficial and surprisingly approachable! Thank you!
24611:01 — emzy running functional tests for the PR now.
24711:01 <theStack> thanks for hosting glozow!
24811:01 <larryruane> thanks glozow!
24911:02 <b_1o1> glozow: thanks for hosting, and achow101
25011:02 <Murch> Thanks for hosting and pinging me ^^
25111:02 <b10c> i think we could do with a bit more documentation/tutorials around the tracing functionally
25211:02 <glozow> Thanks all for coming! Sorry if you were expecting us to stick to the questions, I personally am very happy we didn't. Feel free to ask if you want answers to the questions, I'll be around for a while.
25311:02 <sipa> theStack:
25411:03 <PaperSword> b10c: the purpose of tracing seems to be quite misunderstood and loosely defined.
25511:03 <sipa> GCC 11.3 even warns you that sizeof(int[5] argument) reports sizeof(int*) actually.
25611:03 <PaperSword> just my opinion.
25711:04 <theStack> sipa: interesting!
25811:04 <sipa> Linus Thorvalds has a rant somewhere that you should never ever pass a C array as an argument, because it's so confusing.
25911:04 <pop> Would anyone be willing to break this one down? 6. What’s the difference between the two calls to CreateTransactionInternal? What does it mean to Avoid Partial Spends?
26011:05 <sipa> theStack:
26111:05 <achow101> pop: the avoid partial spends feature groups together all UTXOs for the same address and treats them as a single UTXO during coin selection. This means that all UTXOs for the same address are all spent at the same time.
26211:06 <theStack> sipa: i was hoping that the compiler would at least warn if you'd example access c[5] in func, but apparently it doesn't; so it really treats it just as pointer and that's it
26311:06 <achow101> if avoid partial spends is off (it is off by default), we would do a CreateTransactionInternal without it, then do it again with APS on. Then we choose the "better" of the two solutions
26411:07 <pop> achow101: Is this because, once you spend a single UTXO from the address you will have revealed the private key for that address, rendering all of the associated UTXOs spendable by anyone?
26511:07 <theStack> sipa: always a pleasure to read linus rants :)
26611:07 <achow101> err, not better, but rather we choose the APS one if its fee is not greater than whatever the configured max aps fee is
26711:08 <achow101> pop: no, private keys are never revealed. This is just for privacy. It means that reused addresses won't be mixed with other transactions and thus reveal what utxos are belong to the same person
26811:08 <pop> I see, since a single doxxed address could slowly leak utxos into transactions over time if you don't spend them all
26911:08 <sipa> theStack: Note that C++ has a concept of "pointer to array of specified size", which allows you to actually pass arrays with size information.