19:00:40 <meshcollider> #startmeeting
19:00:40 <lightningbot> Meeting started Fri Feb 28 19:00:40 2020 UTC.  The chair is meshcollider. Information about MeetBot at http://wiki.debian.org/MeetBot.
19:00:40 <lightningbot> Useful Commands: #action #agreed #help #info #idea #link #topic.
19:00:46 <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 moneyball ariard digi_james amiti fjahr
19:00:47 <meshcollider> jeremyrubin emilengler jonatack hebasto jb55
19:00:51 <kanzure> hi
19:00:54 <achow101> hi
19:00:56 <provoostenator> hi
19:01:08 <jonatack> hi
19:01:37 <meshcollider> We have quite a few PRs very close to merge, so I'll go through them today
19:01:49 <meshcollider> Topics?
19:02:46 <achow101> descriptor normalization? (not really wallet though)
19:02:50 <provoostenator> topic suggestion multisig wallet creation
19:04:13 <achow101> multisig wallet creation?
19:05:23 <provoostenator> #18142
19:05:24 <gribble> https://github.com/bitcoin/bitcoin/issues/18142 | Coordinate multi-sig wallet · Issue #18142 · bitcoin/bitcoin · GitHub
19:06:01 <provoostenator> I'm trying to come up with a (file) format that can be used to setup a multisig wallet.
19:06:19 <provoostenator> So far I was able to implement something in JSON.
19:06:35 <provoostenator> I plan to write a script that can convert HWI output to that format...
19:06:39 <achow101> I feel like this is achievable using miniscript policies
19:06:50 <achow101> the only issue being determining the threshold
19:06:53 <provoostenator> Yes, that's what it uses
19:07:09 <provoostenator> There is a global policy, thresh_m
19:07:14 <provoostenator> And then each signer gives a sub policy
19:07:25 <provoostenator> Which are then combined into a wallet policy
19:07:55 <provoostenator> In my example it's the most trivial policy possible, because in practice most walelts can only do a regular multisig of pubkeys
19:08:43 <provoostenator> But the format allows for as complex a (sub)policy as you want, if wallets understand it.
19:09:03 <achow101> it would be preferable to be able to compose, and recursively compose, arbitrary miniscript policies
19:09:26 <meshcollider> Isn't that what hes saying
19:09:37 <provoostenator> Yes, minus the recursive bit
19:09:54 <meshcollider> When would recursive composition be useful
19:09:55 <sipa> miniscript policies can be composed, but the resulting (optimal) scripts aren't a composition of the constituent policies
19:10:19 <sipa> provoostenator: what fo you need beyond miniscript policies in your format?
19:10:31 <provoostenator> Correct, but for dumb wallets I'm thinking of a policy "compiler" that is extremely dumb
19:10:47 <provoostenator> So that the end result can only be check_multisig
19:11:08 <achow101> meshcollider: I was thinking something like participant_1 is really a multisig of participant_4 and 5
19:11:18 <achow101> but that sub policy hasn't been constructed yet
19:11:23 <provoostenator> Here's tesnet example: https://gist.github.com/Sjors/c7342cb27a7cf5f2d35469bb06eae4f4
19:12:53 <achow101> what's not clear to me is why we need a file format?
19:13:10 <provoostenator> Well, so far it's just a JSON format, doesn't ahve to be a file
19:13:10 <achow101> can't you just pass around a miniscript policy, maybe with placeholders, and let people add things to it?
19:13:16 <provoostenator> But it's something you can pass around
19:13:28 <provoostenator> It contains sub policies for each signer
19:13:30 <provoostenator> And keys
19:13:49 <provoostenator> And optionally a friendly name and info about capabilities
19:14:04 <provoostenator> One of the participants can collect that info and combine it.
19:14:24 <provoostenator> And then figure out the overall policy, miniscript and descriptor. And then send that back to the participants
19:15:14 <provoostenator> It would be nice if miniscript supported actual placeholders though
19:15:34 <achow101> I guess what I'm asking is why can't you just pass around a single miniscript policy string that people modify
19:15:36 <provoostenator> Then you can announce the overal policy _before_ collecting info from indiviual signers.
19:16:09 <provoostenator> Oh I see, that's possible too, but it requires that participants actually can parse miniscript, which I'm not assuming
19:16:45 <provoostenator> Simple string concatenation is enough to handle the format I have so far.
19:16:46 <instagibbs> oh hi
19:17:01 <meshcollider> Is the assumption that all the participants are completely trustworh
19:17:08 <meshcollider> Trustworthy*
19:17:10 <achow101> but participants have to be able parse miniscript at the end anyways, no?
19:17:24 <provoostenator> meshcollider: there's room for arbirary fields, so they don't have to be
19:17:44 <achow101> you have to trust participants to not mess with other participant's policies
19:17:59 <provoostenator> There's also room for e.g. musig related info, not something that would fit in a miniscript policy that you pass around
19:18:17 <meshcollider> achow101: idk if that's an assumption we want to make?
19:18:44 <instagibbs> meshcollider, sure seems like something an attacker might do
19:19:04 <achow101> meshcollider: well at the end, you can verify whether you are still in the policy
19:19:22 <achow101> and under what conditions your sub policy would be reached
19:19:27 <achow101> that's the point of miniscript
19:19:47 <sipa> provoostenator: the participants need to be able to reason about the policy of the final descriptor that comes out
19:19:55 <sipa> miniscript enables that
19:19:58 <provoostenator> You probably have to check the first receive address via some other channel to make sure everyone is looking at the same policy
19:20:16 <sipa> without generic script.reasoning logic like that i don't think what you're trying is secure
19:20:19 <provoostenator> Miniscript enables it in the general case.
19:20:23 <achow101> provoostenator: but for musig, and taproot in general, I would expect there to be different miniscript things for that
19:20:30 <provoostenator> But in the simple case you can still reason about thresh(2,pk(3442193e),pk(bd16bee5))
19:20:41 <instagibbs> I think spelling out exactly what you're enabling and protecting against would help for your PoC
19:20:41 <sipa> sure
19:20:52 <provoostenator> I'm trying to make it useful pre-miniscript, but in a forward compatible format.
19:21:23 <sipa> i suspect getting people to adopt a file format will be harder and slower than integration of miniscript :)
19:21:35 <provoostenator> instagibbs: personally I'm happy if it can do m-of-n with devices that I initially trust
19:21:46 <sipa> especially when its usefulness is extremely likited before that poijt in time
19:21:46 <instagibbs> provoostenator, ok, that we can reason about with nothing too fancy :)
19:21:59 <instagibbs> miniscript really does need network effects to be worth it
19:22:03 <provoostenator> Yes, the ad hoc format used by ColdCard does the trick
19:23:11 <instagibbs> meanwhile I think pressuring hww devs to support things like display xpub, register some sorta descriptor like thing, is the best thing to do
19:23:42 <meshcollider> True
19:23:42 <instagibbs> gets you usable n-of-m at least
19:23:43 <provoostenator> So ColdCard registers xpubs, I don't think any other hww does anything similar
19:23:58 <instagibbs> provoostenator, indeed, btchip says it's on the roadmap(no convincing needed at least)
19:24:08 <achow101> I would prefer people to just use miniscript and then compose policies within a miniscript policy itself, rather than a file format
19:24:25 <provoostenator> This may be a chicken-egg thing where people want a standard first, but a standard is hard to develop without practical experience.
19:24:51 <provoostenator> achow101: first thing we'd need for that is xpub & origin support in descriptors
19:25:29 <provoostenator> And ideally placeholder support, so a signer knows where they can insert stuff
19:25:33 <sipa> it's already there?
19:25:44 <achow101> in miniscript you mean?
19:25:44 <sipa> (xpub and origin support)
19:25:51 <provoostenator> sipa on your site I could only add pk(fingerprint)
19:26:00 <provoostenator> Or you mean your PR?
19:26:01 <bitcoin-git> [13bitcoin] 15Empact opened pull request #18226: refactor: Consolidate unnecessary base58 interfaces (06master...062020-02-base58) 02https://github.com/bitcoin/bitcoin/pull/18226
19:26:40 <achow101> I expect that the existing xpub, origin, and general KEY expression stuff in descriptors will be in miniscript
19:26:42 <sipa> provoostenator: ah you mean in miniscript
19:26:53 <provoostenator> yes
19:26:57 <sipa> the compiler just passes through whatever key expressions you use
19:27:07 <sipa> into the descriptor outout
19:27:12 <provoostenator> So e.g. wallet 1 starts and wants to invite 1 more wallet
19:27:13 <sipa> it trats them as strings
19:27:54 <provoostenator> Wallet 1 announces thresh_m(2, c_pk(xpub...),FREE_SPOT_FOR_YOU)
19:28:09 <provoostenator> And then wallet 2 fills in that spot,
19:29:08 <sipa> the hard part is letting wallets verify that the resulting script/descriptor includes the policy they want
19:29:24 <sipa> which isn't implemented in my c++ miniscript code
19:29:31 <sipa> rust-miniscript may
19:29:52 <achow101> sipa: I believe rust-miniscript lets you "pull up" a miniscript to the policy
19:29:55 <instagibbs> "they want" seems like another patch of thorns
19:30:19 <achow101> andytoshi also said it was trivial to do so
19:32:43 <sipa> yeah, it is
19:33:05 <instagibbs> not sure what "pull up" means exactly but I'll defer that to me actually learning miniscript
19:33:22 <sipa> instagibbs: compiler goes from policy to miniscript
19:33:41 <sipa> "pull up" means going the other direction
19:33:47 <sipa> that step is easy
19:33:54 <achow101> "decompile miniscript"
19:33:55 <sipa> but then reasoning about the policy may not be
19:34:08 <instagibbs> i see, you mean someone brings compiled miniscript, you can graft it in, sure
19:34:15 <sipa> no
19:34:35 <instagibbs> ohhh sorry misreading
19:34:45 <instagibbs> way over-reading what achow said, ignore
19:34:49 <sipa> it's just about: someome gives you a script, figure out what it "does", semantically
19:35:01 <instagibbs> yes
19:36:16 <sipa> like... someone "included" your policy in a compiled script
19:36:20 <meshcollider> Because you don't only want to check your spending condition, you really need to check no other paths have been added that shouldn't be there
19:36:27 <sipa> maybe they combined it with an and(X,false)
19:36:56 <sipa> meshcollider: indeed
19:37:19 <instagibbs> "should be" lots of worms in cans ;P
19:37:43 <instagibbs> n-of-m is good or bad depending on who is in the set
19:37:43 <sipa> or did they compile it into a ridiculously inefficient script?
19:39:44 <sipa> i think what may be generically possible is where you have a super-policy super(A,B,C) that is agreed upon out of band (e.g. 2-of-3 multisig)
19:39:56 <sipa> and then let participants fill in their own A, B C
19:40:20 <sipa> the composability of policies means that you generally shouldn't care about what others' A B and C are
19:40:30 <meshcollider> Isn't that what provoostenator did anyway
19:40:38 <meshcollider> Well, limiting super = thresh
19:41:16 <instagibbs> Provided you're talking to the right folks gathering A,B,C, I think so :)
19:41:37 <sipa> the hard part in this case is where does the super-policy come from
19:41:44 <provoostenator> meshcollider: not limiting the policy, but even limiting the compiler
19:42:14 <provoostenator> *not only
19:47:54 <meshcollider> Alright achow101 do you want to talk about descriptor normalisation now
19:48:15 <achow101> sure
19:48:25 <meshcollider> I think the multiwallet needs more thought out of meeting
19:48:34 <meshcollider> Multisig wallet*
19:48:50 <instagibbs> (topic for coredev)
19:48:50 <achow101> we can add it to kanzure's list of discussion topics
19:49:06 <kanzure> okay
19:49:16 <achow101> I kind of tried to do this descriptor xpub normalization in #18163
19:49:18 <gribble> https://github.com/bitcoin/bitcoin/issues/18163 | descriptors: Use xpub at last hardened step if possible by achow101 · Pull Request #18163 · bitcoin/bitcoin · GitHub
19:49:53 <achow101> closed it in favor of the xpub cache, but I think it might still be useful to do
19:50:46 <achow101> basically if we get a descriptor with a xprv and a bunch of hardened steps, then we can make an equivalent descriptor which has the xpub at the last hardened step and the hardened steps and that xprv become the origin info
19:52:06 <achow101> we lose the ability to round trip such descriptors, but I think it's still useful to be able to do this for things like exports
19:52:10 <provoostenator> That seemed sane to me
19:53:10 <achow101> we can also go a step further and do it to all descriptors with xpubs, just derive as far as possible
19:53:34 <achow101> it's all the same at the end, just might be confusing to users
19:53:51 <meshcollider> Derive even the non-hardened steps and just have the  /* at the end?
19:54:15 <achow101> yeah
19:54:34 <provoostenator> I find hardened a more intuitive place to cut off
19:54:51 <provoostenator> It also keeps the xpub in the expected place for BIP44/49/84 style descriptors
19:54:57 <meshcollider> Yeah I don't think there's any point to doing work that anyone else could do anyway
19:55:15 <achow101> it has the effect of making the xpub cache part of the descriptor
19:55:28 <achow101> since in xpub cache, we derive as far as possible and cache that xpub
19:55:49 <provoostenator> I think that cache policy should just be internal
19:56:27 <meshcollider> Yep I can see maybe why xpriv/hardened -> xpub is useful but not other than that
19:56:48 <achow101> less derivations to do
19:57:45 <provoostenator> That seems like a tiny benefit compared to loading a wallet and expanding 1000 keys
20:00:17 <achow101> so with just the hardened derivation, that's something people think we should still try?
20:00:44 <achow101> I think the main concern is that we lose information
20:01:16 <sipa> it's only human-relevant information
20:01:30 <sipa> as the semantics of the normalized descriptor are the same as the original
20:02:23 <achow101> right, but if getdescriptorinfo returned a normalized descriptor, that would probably confuse people
20:02:24 <sipa> but i'm still hesitant to just always do it
20:02:29 <sipa> agree
20:02:43 <sipa> it seems unnecessary, except perhaps in certain opt-in cases
20:03:27 <achow101> the main use is imports into our wallet, and exporting watch only to other wallets
20:04:00 <sipa> but you could do it at export time?
20:04:34 <achow101> it would require access to private keys
20:04:39 <achow101> it'd be nice if it didn't
20:04:47 <sipa> or to the xpub cache?
20:05:11 <achow101> with the xpub cache, it would give the xpub at the end of derivation
20:05:26 <sipa> which is just as good, no?
20:05:34 <achow101> still confusing to users
20:05:46 <sipa> not more so than an xpub in the middle?
20:05:55 <achow101> and possibly to wallets that may try to interpret the derivation info to figure out change/not-change
20:06:09 <provoostenator> Especially the latter
20:06:13 <sipa> the origin info would still be there
20:06:14 <achow101> (I suspect that would be something that wallets try to do)
20:06:18 <sipa> which would have that information
20:06:44 <provoostenator> E.g. with a ColdCard you register an xpub, which covers receive and change
20:06:58 <provoostenator> So it would be confused by a desciptor that has the xpub 1 level down
20:07:15 <provoostenator> Then again, you can't really export a single descriptor anyway
20:07:41 <achow101> I suppose we can bring this up again once we get to allowing descriptor exports
20:07:46 <sipa> yeah
20:08:16 <provoostenator> I wouldn't mind being able to describe receive and change  in  single descriptor, but that's another can of worms.
20:08:26 <sipa> yes :)
20:08:32 <achow101> xpub cache covers what we need to do now, so we can think on this later :)
20:08:39 <bitcoin-git> [13bitcoin] 15MarcoFalke pushed 2 commits to 06master: 02https://github.com/bitcoin/bitcoin/compare/5ad80bec3f31...9aa8145bc024
20:08:40 <bitcoin-git> 13bitcoin/06master 1454be4e7 15Sebastian Falbesoner: test: check specific reject reasons in feature_csv_activation.py
20:08:41 <bitcoin-git> 13bitcoin/06master 149aa8145 15MarcoFalke: Merge #17959: test: check specific reject reasons in feature_csv_activatio...
20:09:00 <instagibbs> oh we're 8 minutes over
20:09:03 <bitcoin-git> [13bitcoin] 15MarcoFalke merged pull request #17959: test: check specific reject reasons in feature_csv_activation.py (06master...0620200118-test-check-reject-reasons-in-feature-csv-activation) 02https://github.com/bitcoin/bitcoin/pull/17959
20:10:30 <achow101> any other topics?
20:10:57 <instagibbs> PSBT GUI review: do it
20:11:12 <gwillen> apropos of that actually instagibbs, I saw you commented about showing change addresses
20:11:28 <gwillen> I am pretty fuzzy on the story of "safely detecting change addresses" in this setting
20:11:48 <achow101> Change detection is always fuzzy
20:11:50 <provoostenator> On the send dialog you can know which one is change
20:11:59 <provoostenator> On the load PSBT I wouldn't bother for now.
20:12:01 <instagibbs> in normal sends it ellides those outputs... but PSBT signing is not the typical case, in many cases
20:12:10 <instagibbs> provoostenator, right
20:12:11 <gwillen> yeah, my assumption was not to bother for signing, and to show all addresses
20:12:37 <provoostenator> It's probably some property on rcp that you can look at, the normal confirm dialog knows.
20:13:03 <sipa> you can show the net balance effect a transaction has on your wallet, independent of knowing what is change or not, right?
20:13:14 <gwillen> not when signing, no wallet
20:13:24 <achow101> no wallet?
20:13:28 <sipa> ah, without wallet you can't even talk about the concept of change
20:13:33 <instagibbs> it might be a dumb key store
20:13:35 <instagibbs> achow101,
20:13:37 <gwillen> well, hm, I guess I am assuming that in general, when signing offline, you are just a dumb key store, yeah
20:13:57 <gwillen> you may not have the blockchain, and you may only have keys to some subpart of whatever inputs you're signing for
20:14:09 <sipa> gwillen: well a sane key store (one that can verify what it's signing) must have a pre-registered descriptor set
20:14:11 <achow101> For change detection, you should be able to just ask the wallet if a particular destination IsChange and do your change detection like that
20:14:22 <achow101> but that assumes the PSBT belongs to that wallet
20:14:24 <sipa> gwillen: if you don't have that, talking about balance or change is meaningless
20:14:27 <gwillen> sipa: do we have a sane key store, though, in the sense
20:14:35 <achow101> gwillen: we will soon(tm)
20:14:47 <sipa> gwillen: well, our wallet is
20:14:58 <gwillen> in particular, the case I am most interested in is signing for a multisig
20:15:01 <provoostenator> Right, fun fact about the current keystore: getrawchange address wil give you an address from the receive chain
20:15:20 <gwillen> in which case there is a lot more information needed before one could safely conclude that some output is "change"
20:15:27 <sipa> my point is just that if you want to do signing without such knowledge (which is a totally reasonable thing to do in some cases), you must accept that that means there is no such thing as change detection and shouldn't bother
20:15:32 <gwillen> *nods*
20:15:41 <instagibbs> gwillen, well, is today's wallet IsChange would fail for any multisig address
20:15:44 <gwillen> anyway instagibbs this was apropos of your comment asking why we display the change
20:15:50 <instagibbs> if its a descriptor wallet change-ness is stored
20:15:58 <instagibbs> anyways, it's fine for now
20:16:05 * sipa -> lunch
20:16:05 <gwillen> the answer is that I'm assuming in almost any interesting case we can't tell
20:16:17 <gwillen> and so there's no point in special-casing the boring cases where we can
20:16:20 <instagibbs> gwillen, disagree I think?
20:16:30 <achow101> gwillen: I don't think that's an assumption in descriptor wallets
20:16:43 <achow101> since in descriptor wallets you import the descriptor and mark it as change or not
20:16:44 <gwillen> well we don't have those yet, so
20:16:51 <gwillen> when we have those I will revisit :-)
20:17:06 <sipa> i don't see what descriptor wallets have to do with this, actually
20:17:18 <sipa> either you have a wallet, and you can ask what it would consider change
20:17:23 <sipa> or you don't
20:17:31 <achow101> you can do the same change detection stuff now as you would in the future, it's exposed in the same way
20:17:43 <achow101> we just won't detect multisig or funny script things as change
20:17:52 <instagibbs> `IsChange()` works for random imports already AFAIK, you just can't put in keypool
20:17:56 <meshcollider> Anyway I think let's end the official meeting
20:17:59 <meshcollider> #endmeeting