19:00:45 <meshcollider> #startmeeting
19:00:45 <lightningbot> Meeting started Fri Mar  1 19:00:45 2019 UTC.  The chair is meshcollider. Information about MeetBot at http://wiki.debian.org/MeetBot.
19:00:45 <lightningbot> Useful Commands: #action #agreed #help #info #idea #link #topic.
19:00:47 <provoostenator> hi
19:00:48 <sipa> present
19:00:51 <meshcollider> #bitcoin-core-dev Wallet Meeting: wumpus sipa gmaxwell jonasschnelli morcos luke-jr sdaftuar jtimon cfields petertodd kanzure bluematt instagibbs phantomcircuit codeshark michagogo marcofalke paveljanik NicolasDorier jl2012 achow101 meshcollider jnewbery maaku fanquake promag provoostenator aj Chris_Stewart_5 dongcarl gwillen jamesob ken281221 ryanofsky gleb
19:00:58 <instagibbs> hi
19:01:17 <meshcollider> Topics for this week?
19:01:31 <achow101> Hi
19:01:50 <sipa> i guess there isn't anything wallet-related for 0.18
19:02:27 <provoostenator> #15453
19:02:29 <gribble> https://github.com/bitcoin/bitcoin/issues/15453 | Starting bitcoin-qt with -nowallet and then opening a wallet does not show the wallet · Issue #15453 · bitcoin/bitcoin · GitHub
19:02:36 <provoostenator> Is tagged with 0.18 anyway
19:03:02 <provoostenator> With a cliff-hanger from promag
19:03:23 <meshcollider> That's a Qt issue though right
19:03:59 <achow101> It only effects people who self compile
19:04:26 <achow101> As the issue is with qt versions
19:06:21 <provoostenator> It seems so, in which case it should be OK as long as we backport the fix onto the 0.18 branch.
19:07:17 <meshcollider> Mhm
19:07:35 <meshcollider> Other than that, yeah, we managed to get all the wallet PRs for 0.18 reviewed and merged pretty efficiently so nice work
19:09:11 <provoostenator> Proposed topic: descriptor based wallets
19:09:36 <provoostenator> (briefly anyway, since everyone is focussed on 0.18)
19:11:30 <provoostenator> sipa: one thing we talked about before that would be useful for my HWW PR is away to compose descriptors in code
19:12:01 <provoostenator> If you're able to whip up an example for e.g. sh(wpkh(xpub)) I can probably figure out the rest
19:12:25 <provoostenator> It's just my C++ is a bit rusty when it comes to unique_ptr and abstract classes.
19:12:38 <sipa> provoostenator: it's not that trivial anymore in the current code
19:12:56 <sipa> i briefly had a look, but it would need some restructuring
19:13:07 <provoostenator> Ok, glad to know it's not just me :-)
19:14:33 <provoostenator> The use case here is that we fetch an xpub from a hardware wallet and then construct a descriptor with that.
19:14:45 <sipa> with the 0.18 things out of the way, i'll try to find time to do the ismine/keypool abstraction i've talked about before
19:15:13 <provoostenator> ismine/keypool stuff also very useful.
19:16:12 <provoostenator> An alternative approach would be to be require the hardware wallet (driver) to give a full descriptor, or a set of potential desrciptors from which we pick one or more.
19:16:39 <meshcollider> #topic descriptor based wallets
19:16:47 <provoostenator> But that choice shouldn't be determined by implementation details such as this I think.
19:17:02 <sipa> provoostenator: you can always construct the descriptor in string form
19:17:25 <sipa> i agree that's suboptimal, but it means having an API to construct descriptors shouldn't be a blocker
19:17:47 <provoostenator> That's what I'm doing in the prototype.
19:18:15 <instagibbs> I've done this previously as well, constructing manually
19:18:18 <provoostenator> There's not really any blockers left in that PR, so I'm mostly focussing on getting it merge-worthy.
19:19:19 <provoostenator> Although it would be safer when combined with native-descriptor wallets, because the behavior of getnewaddress doesn't jive well with BIP44/49/84 that wallets use.
19:19:45 <provoostenator> (that hardware wallets tend to use)
19:19:55 <instagibbs> provoostenator, you're safe as long as you don't use getnewaddress with a watchonly wallet :D
19:20:24 <meshcollider> are hardware wallets working on implementing things like returning descriptors?
19:20:26 <provoostenator> instagibbs: so you use deriveaddresses?
19:20:43 <instagibbs> provoostenator, no I just assume people aren't going to dust my cold wallet :P
19:20:49 <provoostenator> meshcollider: not that I know, but HWI python coud easiliy do that.
19:20:56 <instagibbs> meshcollider, unlikely to get that standardized, no
19:21:15 <meshcollider> Mhm
19:21:30 <instagibbs> ledger has basically said they won't bother supporting PSBT like ever
19:21:42 <meshcollider> Oh, thats a shame
19:21:43 <instagibbs> I can't imagine they'd do descriptors
19:21:46 <sipa> well they don't need to
19:21:52 <instagibbs> sipa, right, it's fine
19:22:07 <instagibbs> just giving context
19:22:09 <sipa> i mean: i wouldn't even recommend that hw wallets directly implement psbt
19:22:18 <sipa> all you need is a software driver that supports it
19:22:25 <sipa> same with descriptors
19:22:36 <sipa> they're a software (and bitcoin core specifically...) kinda thing
19:22:58 <provoostenator> Basically Bitcoin Core could give an account number and then HWI would, if the device supports SegWit return three descriptors: "pkh([44'/0'/account]xpub/0/*])", "sh(wpkh([49'/0'/account]xpub/0/*]))" and "wpkh([84'/0'/account]xpub/0/*])" (plus change), and then our wallet imports one or all
19:23:10 <achow101> hwi already uses descriptors
19:24:04 <provoostenator> But the current importmulti logic doesn't handle the above correctly, native descriptor wallets would.
19:24:30 <provoostenator> So then you can get a bech32 address and it will grab it from the wpkh(84' tree, or fail if that's absent.
19:25:45 <provoostenator> We probably only need two address types: default and wrapped-segwit. Default is either legacy pkh() or native segwith (wpkh or script hash).
19:26:17 <sipa> you'd mark certain records as the provider for certain types of addresses
19:27:43 <sipa> if you don't have one for native segwit addresses, then requesting a native segwit address will fail
19:28:15 <provoostenator> Right, I guess it's fine to hold on to the current address_type concept then.
19:28:29 <provoostenator> legacy, p2sh_segwit and bech32
19:28:48 <provoostenator> But simply fail if the right descriptor isn't available.
19:29:27 <provoostenator> Do descriptors needs to "marked" for that? Or can you just infer it?
19:29:50 <meshcollider> The default ones would need to be marked in case you have others too
19:29:58 <sipa> well i'm imagining you can have multiple records
19:32:13 <provoostenator> One default record in case there's multiple records of the same address type.
19:32:13 <sipa> (especially if you have a wallet that at some point switched over to a new key/descriptor/hwwallet for whatever reason, but still want to keep access to old transaction history with the previous ones)
19:32:13 <provoostenator> I was thinking of adding a purpose enum: receive, change, other
19:32:13 <sipa> yes
19:32:14 <provoostenator> For each address type there can only be one descriptor with receive/change
19:32:23 <sipa> why?
19:32:32 <provoostenator> Because that indicates the default
19:32:47 <sipa> what a descriptor is used for should be independent of whether it's the default imo
19:32:54 <provoostenator> That makes sense
19:33:06 <provoostenator> So then in addition to purpose, we also need to track the default descriptors.
19:33:11 <sipa> if you transition to a new one, the one you used for change before doesn't stop being change
19:33:52 <sipa> i think that's all in https://gist.github.com/sipa/125cfa1615946d0c3f3eec2ad7f250a2 already
19:34:11 <provoostenator> How do we identify descriptors if there's more than one? Just an increasing int as we add them, or by their checksum (seems brittle) or something else?
19:34:48 <sipa> seems like an implementation detail
19:35:38 <provoostenator> Well, it matters for RPC arguments, but for now I'm avoiding that problem by not allowing more than one of each purpose :-)
19:36:11 <sipa> do you need to expose internal identifiers?
19:36:44 <sipa> (i haven't thought much about this)
19:36:51 <meshcollider> Identify them by checksum :p
19:37:28 <sipa> if so, it seems best that records have a unique user-provided name, and you use that name in rpc to refer to them
19:37:31 <provoostenator> sipa: getnewaddress "Buy new cow" bech32 [how do I tell which non-default descriptor to use]
19:37:48 <instagibbs> why not force them to switch first, then call getnewaddress
19:37:50 <sipa> provoostenator: is that necessary?
19:38:00 <provoostenator> Name makes sense
19:38:08 <sipa> provoostenator: you can't getnewaddress from an old keypool now either
19:38:21 <meshcollider> Other records are more for things like watch-only, etc
19:38:38 <meshcollider> Internal stuff
19:38:42 <provoostenator> True, if non-default descriptors can only be used for archival purposes then there's no need to support them in getnewaddress
19:39:03 <sipa> that's what i was thinking yes; they're just there to not lose old transaction history
19:39:07 <sipa> or to watch
19:39:12 <provoostenator> It also depends on how much we want to push for 1-wallet-1-goal
19:39:23 <provoostenator> Rather than put-whatever-you-want-in-a-single-walllet
19:40:09 <sipa> right; but in a pure watch-only wallet (where "watch only" truly means you're watching someone else's wallet, not just "i don't have the private key right here"), you probably don't want to have any "default newaddress provider"
19:40:15 <provoostenator> I also prefer keeping wallets simple in that sense, especially to keep the GUI sane.
19:40:19 <sipa> because there shouldn't be a way to create new addresses
19:41:29 <provoostenator> Agree that getnewaddress should require >= IsSolveable
19:41:40 <sipa> descriptors are always solvable
19:41:59 <sipa> (except the "raw" and "script" ones, but those can't be used to derive anything anyway)
19:42:06 <provoostenator> Ah yes
19:42:12 <sipa> solvability is not the point
19:42:37 <meshcollider> thats the difference between is "mine" and is "spendable"
19:43:04 <sipa> so right now "watchonly" means "i don't happen to have the private key in my wallet.dat file"
19:43:10 <sipa> i think that's a mistake
19:43:44 <meshcollider> Agree, this rework is the perfect time to tighten up definition of things like that too
19:43:45 <sipa> the distinction between "my money" and "watched money" is useful, but it's somewhat independent from where the private keys live
19:44:23 <sipa> especially in a hwwallet/offline storage/... kinda world... the case where the private key is actually in your wallet.dat file (even for your own coins) should be the exception
19:45:34 <sipa> oh, i guess i should bring this up here, i did a talk at SBC19 about miniscript, and i'll work on getting support for it in core
19:45:53 <sipa> so that our signer (including psbt, etc) can deal with more complicated scripts than just single key and multisig
19:46:46 <provoostenator> So we can do things like GreenAddress style multisig or timeout & single sig?
19:46:50 <sipa> yeah
19:47:16 <meshcollider> Was the talk recorded
19:47:28 <sipa> https://www.youtube.com/watch?v=XM1lzN4Zfks
19:47:34 <meshcollider> Thanks
19:47:38 <provoostenator> I wonder what the setup UX would look like if e.g. you had two hardware wallets and wanted such a 2-of-2 or timeout & 1-of-2.
19:47:53 <sipa> provoostenator: that's a question for you :)
19:48:00 <sipa> i'm perfectly fine with psbt rpcs :P
19:48:20 <instagibbs> gui coin control tho
19:48:20 <achow101> sipa: replacing the signer with miniscript would probably be a good time to also distinguish between signing and finalizing
19:48:32 <sipa> achow101: hmm?
19:48:55 <provoostenator> Right, I guess there would be an RPC where you give it a meta-descriptor or miniscript, then it goes and fetches xpubs from both devices in sequence and imports the right descriptors
19:49:11 <provoostenator> Plus asking some sanity check questions to the driver like "can you sign stuff with nlocktime"
19:49:20 <achow101> ProduceSignature makes both the signature and scriptSig/witness
19:49:20 <instagibbs> provoostenator, the descriptor will be parsed into miniscript, afaik
19:49:25 <sipa> provoostenator: the workflow is that you'd use the miniscript compiler to convert a policy to a descriptor
19:49:28 <instagibbs> ^
19:49:29 <sipa> and then import the descriptor
19:49:30 <instagibbs> yeah
19:49:42 <sipa> the compiler could be built-in, but doesn't need to be
19:49:51 <provoostenator> Do you put xpubs in the miniscript or does that happen later?
19:50:00 <achow101> But under the psbt model, those should be distinct.
19:50:06 <sipa> provoostenator: yeah
19:50:17 <sipa> the compiler just passes those though, i imagine
19:50:58 <sipa> (miniscript is just the name of the subset of script; i use "policy" language to refer to the input of the compiler)
19:51:06 <sipa> i know, i suck at naming things
19:51:21 <sipa> and this is genuinely confusing because there are several things that look kinda similar
19:51:47 <provoostenator> signerfetchkeys "miniscript with rules $device_fingerprint_1  $device_fingerprint_1"
19:51:50 <sipa> achow101: yeah, i guess it can simplify things if we split up the signer and finalizer in the code too
19:51:53 <provoostenator> Piece of cake
19:54:48 <meshcollider> Is there anything else anyone wants to talk about in the last few minutes
19:58:53 <meshcollider> #endmeeting