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