--- Day changed Sun Nov 29 2020 01:03 -!- shesek [~shesek@unaffiliated/shesek] has joined ##miniscript 01:09 -!- jeremyrubin [~jr@c-73-15-215-148.hsd1.ca.comcast.net] has quit [Ping timeout: 240 seconds] 02:09 < afilini> dariosor: yeah I think it looks good the way you've done it 02:10 < afilini> and I made a typo in your name, sorry darosior :/ 02:14 -!- afilini [~user@gateway/tor-sasl/afilini] has quit [Remote host closed the connection] 02:57 < darosior> afilini: ok, thanks! 02:57 < darosior> Sure :) 02:58 < darosior> sanket1729_: but as andytoshi pointed out (00:38), this would be detected at parse time ? 05:49 < andytoshi> it might not be if you use parse_insane 05:50 < andytoshi> sanket1729_: do you know offhand if there are standardness rules that apply to the witness script by itself? 05:50 < andytoshi> that are not consensus rules? 06:25 -!- shesek [~shesek@unaffiliated/shesek] has quit [Remote host closed the connection] 06:46 < darosior> andytoshi: iirc there is the script size that is part of policy 06:49 < andytoshi> sigh why is bitcoin so weird 06:50 < andytoshi> yeah, i see, it's on pieter's miniscript page, there's a 3600 byte limit 06:50 < andytoshi> oh, i think though, "insane" does not mean "nonstandard" 06:52 < andytoshi> yeah ok phew 06:52 < andytoshi> darosior: ok, so sanket1729_'s comment on the PR is right ... we always (sane or insane) check global policy limits when parsing 06:53 < andytoshi> i don't think there's anywhere in rust-miniscript where we allow non-standard things to slip by 06:53 < darosior> andytoshi: so we should drop the checks at satisfaction time ? 06:53 < andytoshi> yep 06:55 < andytoshi> an unrelated thing that i've been musing about ... if we have a script that you can satisfy, but only if you grind your signatures to be tiny, we do the right thing there right? 06:55 < andytoshi> that is, when we're actually satisfying, we don't assume signatures are 73 bytes anymore, we use the actual signature size? 06:56 < darosior> I think they always are 71 ? 06:56 < darosior> At least i've assumed so 06:57 < andytoshi> are you disputing my specific number, or the general crux of what i'm saying? 06:57 < andytoshi> 71 sounds like a normal sig but i think our worst-case bounds all use 73 06:57 < andytoshi> but i could be wrong 06:58 < darosior> Oh no we account for 73 06:58 < darosior> I was wrong 06:58 < andytoshi> ok .. regardless, we do that when estimating bounds .. but when we're checking our satisfaction limits, we don't do this right? 06:58 * darosior checks 06:59 < darosior> We don't check each witness element size, so i don't think we account for a specific size for the sigs 07:00 < darosior> Maybe for legacy Ctx.. 07:00 < darosior> We do check it for legacy and use 73 07:01 < andytoshi> o.o 07:01 < darosior> But that makes sense, doesn't it ? 07:02 < andytoshi> no, if we're checking whether a satisfaction is valid we have an actual signature 07:02 < andytoshi> so why would we make up a number 07:02 < darosior> I think we check it at parse time, we don't have the satisfaction yet 07:03 < darosior> So we account for the worse-case satisfaction given this script? 07:03 < andytoshi> this isn't a global limit though 07:04 < andytoshi> ok, it looks like the only relevant limits here are MAX_SCRIPTSIG_SIZE (legacy only) and MAX_STANDARD_P2WSH_STACK_ITEMS (which doesn't vary with signature length) 07:04 < andytoshi> i don't expect either to be checked at parse time 07:04 < andytoshi> because they are local properties 07:05 < andytoshi> we also have MAX_SCRIPT_ELEMENT_SIZE and i'm curious when that _ever_ shows up in rust-miniscript.. 07:05 < andytoshi> oh right lol 07:05 < andytoshi> in p2sh scripts are stack elements 07:05 < andytoshi> jeez this is ridiculous 07:05 < andytoshi> anyway 07:06 < andytoshi> as expected ... neither of the two limits i mentioned are checked at parse time. they are both part of Context::check_local_policy_validity 07:07 < darosior> I thought it was called at parse time, my bad. 07:07 < darosior> It's called by the compiler though :) 07:07 < andytoshi> yes :) the compiler will assume 73 bytes 07:07 < andytoshi> and won't ever make policies that you need to grind sigs to satisfy 07:07 < andytoshi> which is probably the right thing :P 07:08 < darosior> But it *could* be checked at parse time, right ? 07:08 < darosior> And probably should then 07:08 < andytoshi> what? MAX_SCRIPTSIG_SIZE? 07:08 < andytoshi> no. it's a local property 07:09 < darosior> Like MAX_ELEMENTS 07:09 < andytoshi> so, we technically could, but i think this would be conceptually confuse]d 07:09 -!- gnusha [~gnusha@unaffiliated/kanzure/bot/gnusha] has joined ##miniscript 07:09 < andytoshi> we refuse to parse scripts which are globally invalid 07:10 < andytoshi> but we don't refuse to parse scripts which have locally invalid branches ... even if every branch is locally invalid for every possible satisfaction 07:10 < andytoshi> we could do that. and then we would need 50 extra words to explain the parsing-time checks and we'd refuse to parse the 0 script 07:11 < darosior> Yeah, right :) 07:11 < andytoshi> (or maybe we wouldn't refuse to parse the 0 script? i guess it doesn't violate any limits .. that would be even more confusing) 07:11 < andytoshi> the 0 script is interesting beceause all satisfactions are locally valid. and all satisfactions are locally invalid 07:12 -!- gnusha [~gnusha@unaffiliated/kanzure/bot/gnusha] has left ##miniscript [] 07:12 < andytoshi> and the above is true with "all" replaced by "no" 07:12 < darosior> How so ? 07:12 < andytoshi> vacuously 07:13 -!- gnusha [~gnusha@unaffiliated/kanzure/bot/gnusha] has joined ##miniscript 07:13 -!- gnusha [~gnusha@unaffiliated/kanzure/bot/gnusha] has left ##miniscript [] 07:13 -!- gnusha [~gnusha@unaffiliated/kanzure/bot/gnusha] has joined ##miniscript 07:14 < darosior> What is an example of a both locally valid and locally invalid satisfaction? 07:14 < andytoshi> there is none. there are no satisfactions of 0 07:15 < andytoshi> that doesn't contradict any of my claims 07:15 < darosior> So you meant "all DIsatisfactions are locally valid" ? 07:15 < darosior> Oh i get it 07:15 < darosior> Because there are none, they are all valid ? 07:16 < andytoshi> no, i didn't say anything about dissatisfactions 07:17 < darosior> So because there is no satisfaction for 0, all satisfactions for 0 are locally valid ? --- Log opened Sun Nov 29 07:17:13 2020 07:17 < andytoshi> darosior: correct 07:17 < darosior> :) 07:19 < andytoshi> sanket1729_: i also can't find anywhere we check MAX_SCRIPTSIG_SIZE when satisfying 07:20 < andytoshi> i also really think we should rename all the check_local functions in Context to check_everywhere_local 07:21 < andytoshi> and add global_ or everywhere_local_ to all the Context methods that don't have one of those already 07:21 < andytoshi> and add actual local checks, which take a satisfaction in some format 07:26 < andytoshi> i guess we'd add an associated type to Context representing a satisfaction. which for segwit stuff would be a Vec> and for legacy would be a Script 07:26 < andytoshi> i can maybe do this today 07:27 < andytoshi> but somehow my weekends are always way overbooked :) 08:01 -!- jeremyrubin [~jr@c-73-15-215-148.hsd1.ca.comcast.net] has joined ##miniscript 10:13 < sanket1729_> andytoshi: we check MAX_SCRIPTSIG size over here https://github.com/rust-bitcoin/rust-miniscript/blob/977a3671a35b3558eaba6f73f1093507176d3781/src/miniscript/mod.rs#L307 10:15 < sanket1729_> andytoshi: right now our satisfier finds witness as Vec>(both in segwit and legacy) 10:15 < sanket1729_> which we then convert to scriptsig and do the checks in check_witness 10:16 < sanket1729_> > i can't find where in the code we refuse to lift scripts which are locally invalid ... i think we only check timelocks 10:16 < sanket1729_> true. that is indeed a bug. I will address that today 10:19 < sanket1729_> darosior: are we on the page for PR #196? Since the checks are satisfaction time(not script creation time), we need to check the stack size(segwit) and scriptsig_size(legacy) 10:19 < andytoshi> oh oops i was on pr196 not master 10:20 < darosior> sanket1729_: yep, will restore my original commit 10:20 < darosior> And remove the SCRIPT_SIZE check, which is checked at parsing time right? 10:20 < sanket1729_> I also agree with andytoshi maybe better names for these things would save us lot of mental reasonin 10:20 < sanket1729_> darosior: yeah 10:21 < andytoshi> 18:16 < sanket1729_> true. that is indeed a bug. I will address that today 10:21 < andytoshi> thanks, though bear in mind that it is a sunday :) 10:21 < sanket1729_> I have been away for 3 days now :) . 10:21 < andytoshi> ok :) 10:22 < sanket1729_> even if out names for context checks are very long, we should rename them. 10:23 < darosior> Then i think we should also check for other satisfaction-related limits ? 10:23 < darosior> Like each element size 10:23 < sanket1729_> *end up being long 10:23 < andytoshi> darosior: yeah, those should all be in check_witness 10:23 < sanket1729_> darosior: miniscript never produces anything more than 73 bytes 10:23 < sanket1729_> so, we don't really need to check it. 10:23 < andytoshi> i'm ok with the name check_witness though it could be called check_local to be consistent 10:23 < andytoshi> oh yeah, element size specifically is unnecessary 10:24 < darosior> Ok 10:25 < sanket1729_> I looked over bitcoin core consensus.h and policy.h to find all checks. Right now, the only thing we don't check is whether during the execution the stack + altstack size could be than 1000 elemnts 10:25 < andytoshi> nice 10:26 < andytoshi> and interesting question whether we can hit that without exceeding the initial stack elem limit 10:26 < andytoshi> i guess if you wrap a timelock that takes 0 stack elements and pushes a 1 onto the stack 10:26 < sanket1729_> stack limi is only for segwit 10:26 < andytoshi> ah 10:26 < sanket1729_> I think we can for legacy 10:27 < sanket1729_> but the opcodes is 200 only 10:27 < sanket1729_> so maybe we can't 10:27 < sanket1729_> But we would need that check for Taproot. 10:27 < andytoshi> i think op_1 doesn't count toward the opcode limit 10:28 < sanket1729_> but we also need to drop the timelock 10:28 < andytoshi> yeah 10:28 < andytoshi> i had been thinking just of the 1 fragment by itself 10:28 < sanket1729_> which requires 1 opcode 10:28 < andytoshi> but you can't chain them together without booland or some opcode 10:29 < andytoshi> all in all i'm fairly confident we don't need to check this limit :P 10:29 < andytoshi> though you're right that in taproot there won't be other limits to protect us 10:32 < sanket1729_> I think we also exceed in legacy as follows l:l:l:l:l(time) where l is likely wrapper. the satisfaction would require 1000 op_1 10:32 < sipa> sanket1729_: stack limit is checked after every opcode 10:32 < sipa> in all script types 10:33 < sipa> sum of number of elements on altstack + number of elements on normal stack can't exceed 1000 at any time 10:33 < andytoshi> sanket1729_: i'm confused l: takes op_if/op_else_op_endif 10:33 < andytoshi> which all count toward the opcode limit 10:33 < sanket1729_> ah 10:33 < sanket1729_> oops 10:34 < sanket1729_> right, it is not possible in legacy. 10:35 < sanket1729_> but in tapscript, that could be an issue. I am thinking about whether "checking the initial stack size in miniscript enough for assuring check stack+alt stack size in execution"? 10:37 < sanket1729_> The answer is no. The fragment `thresh(1000, pk, v:time, v:time, v:time, v:time, ....)` has only 1 initial witness, but the stack size might increase to 1000 10:39 < andytoshi> you can't put vs in a threhsold 10:39 < andytoshi> but i think you can just use 1 in place of v:time there 10:39 < sanket1729_> we can make them tv 10:39 < andytoshi> tv still is not d 10:40 < andytoshi> hmm i guess 1 is not either 10:41 < sanket1729_> we can do I think we can do `and_b(time,and_b(time,and_b(time ... ))_` 10:42 < sanket1729_> forgot the :s or :a wrapper for and_b 10:42 < andytoshi> i'm unconvinced, every and_b consumes two stack elems and pushes 1 10:42 < sanket1729_> but we get the element from script and not from initial stack 10:42 < sanket1729_> in case of after/older 10:43 < andytoshi> okay, but it's not increasing the number of stack elements, it's decreasing it 10:43 < andytoshi> 1 adds a single elem. so does and_b(1,1). and so on 10:43 < andytoshi> oh lol i see 10:43 < sanket1729_> it's recursive and_b 10:43 < andytoshi> yep 10:48 < sipa> hmm, did we just forget about this 1000 runtime stack limit? 10:48 < sanket1729_> It is possible to detect whether tapscript miniscripts can exceed that limit. But it is too large that I wonder if it worth the effort. 10:48 < sipa> i have code for reasoning about input stack sizes 10:48 < sipa> bit not for runtime stack sizes 10:49 < sipa> but if we forgot about this, our random fuzzing against core validation should have failed 10:49 < sipa> ah 10:49 < sipa> i think it's impossible to hit this with standard scripts 10:49 < sanket1729_> yep, we are discussing tapscripts 10:49 < sipa> because either the opcode limit, or the input size limit can be exceeded 10:49 < sipa> yep, in tapscript i think we should 18:13 -!- shesek [~shesek@164.90.217.137] has joined ##miniscript 18:13 -!- shesek [~shesek@164.90.217.137] has quit [Changing host] 18:13 -!- shesek [~shesek@unaffiliated/shesek] has joined ##miniscript 21:28 -!- achow101 [~achow101@unaffiliated/achow101] has quit [Quit: Bye] 21:28 -!- achow101 [~achow101@unaffiliated/achow101] has joined ##miniscript 21:31 -!- achow101 [~achow101@unaffiliated/achow101] has quit [Client Quit] 21:31 -!- achow101 [~achow101@unaffiliated/achow101] has joined ##miniscript 23:10 < sanket1729_> sipa, andytoshi: "d" Dissatisfiable: a dissatisfaction for this expression can unconditionally be constructed. What was our rationale for making PkH `d`? 23:13 < sanket1729_> I am starting to think it should not be `d` because the satisfaction might rely on this being easily dissatisfiable and maybe in real life cases multi-party scenario this is not always true 23:16 < sanket1729_> I came across when writing a finalizer for psbt. We additionally require the mapping pkh -> pk which is not a psbt field(as of now) 23:21 < sipa> sanket1729_: in a descriptor scenario it's alwaya true! 23:23 < sipa> and in bip32 settings it's in psbt too (in a hacky way, you can even put it there with an empty derivation path for other pubkeys) 23:26 < sanket1729_> Nice. 23:28 < sipa> in general i think it simplifies things if you assume the participants in a script know everything about it 23:28 < sipa> they shouldn't agree to participate otherwise 23:29 < sipa> and there are of course scenarios where that'd not the case... someone sent coins to a multisig contract that involves you, but yoi had no clue about and want to recover the money 23:29 < sipa> i think in that case it's fine to fail signing if you just happen to not have all the informatiom mecessary 23:30 < sipa> but i don't think it needs to affect typesystem properties, which are more about sanity checking a script before you participate 23:31 < sipa> in a scenario where the coins are already there, you don't need the typesystem anymore arguably... do whatever you can to get the money out 23:31 < sanket1729_> yeah, I agree about the typesystem not being affected. just the wording "unconditionally" in definition of `d` was a bit confusing 23:32 < sipa> well, perhaps we need a formal definition of "conditiom" somewhere 23:32 < sipa> it means "access to private keys, hash preimages, and whether or not timelocks are satisifed" 23:36 < sanket1729_> stepping a bit back, you are saying that in multi-party scenarios parties should not paricipate in the contract if don't have the descriptor(even if they have the complete redeem script) 23:37 < sipa> doesn't need to be in the form of a descriptor 23:37 < sipa> psbt can provide that information too 23:38 < sipa> or whatever system they have that can provide the necessaey information in an application specific manner 23:38 < sipa> but conceptually, yes absolutely 23:39 < sanket1729_> Thanks, this makes sense. 23:40 < sipa> hmm, this is interesting actually... there are probably situations where that's not the case, and it's also unnecessary 23:40 < sipa> nested musig is arguably designed for exactly that 23:41 < sipa> but in that case it's also undetectable... information is missing that you don't know is missing and doesn't affect your ability to sign 23:42 < sipa> you'll need to knos your "sibling" full pubkeys, but not your cousin keys 23:43 < sipa> you may also not know origin info for all pubkeys involved in a script, which may be essential information to someone to sign 23:43 < sipa> but it still doesn't affect your ability to sign 23:44 < sipa> i believe it is the case that whenever you're able to infer a descriptor from the information you have, even if incomplete, (but excluding addr/raw of course), you're good 23:45 < sanket1729_> agreed 23:46 < sanket1729_> Do you think we should have a more cleaner way(pkh->pk) to infer descriptor from psbt? 23:46 < sanket1729_> as an extra field rather than bip32 path info. 23:47 < sanket1729_> The only concern I had was in a multiparty scenario I give Bob gives Alice a script(not descriptor) `or_c(c:pk_h(Hash_bob),pk(Alice))` and Bob can refuse to participate. 23:48 < sanket1729_> andytoshi: Our current semantic analysis in rust-miniscript does not detect this and would say Alice can always spend the funds(which is not true) 23:48 < sipa> there is no need for an extra field, you can use the bip32 one 23:49 < sipa> right, you said that 23:50 < sipa> i don't think "cleaner" is sufficient justification for adding a field :) 23:50 < sanket1729_> sure :) 23:51 < sipa> yeah, i don't think you should permit semantic analysis of you can't infer a descriptor 23:54 < sipa> i guess that takes things even further along the path of "miniscript itself is just a component, you really need it in the context of descriptors" --- Log closed Mon Nov 30 00:00:31 2020