--- Day changed Tue Jul 07 2020 00:30 -!- dr-orlovsky [~dr-orlovs@adsl-62-167-101-63.adslplus.ch] has quit [Quit: My MacBook has gone to sleep. ZZZzzz…] 00:30 -!- dr-orlovsky [~dr-orlovs@adsl-62-167-101-63.adslplus.ch] has joined ##miniscript 04:09 -!- dr-orlovsky [~dr-orlovs@adsl-62-167-101-63.adslplus.ch] has quit [Quit: My MacBook has gone to sleep. ZZZzzz…] 06:26 -!- jonatack [~jon@2a01:e0a:53c:a200:bb54:3be5:c3d0:9ce5] has quit [Quit: jonatack] 06:31 -!- jonatack [~jon@2a01:e0a:53c:a200:bb54:3be5:c3d0:9ce5] has joined ##miniscript 06:42 -!- dr-orlovsky [~dr-orlovs@194.230.155.196] has joined ##miniscript 06:46 -!- dr-orlovsky [~dr-orlovs@194.230.155.196] has quit [Client Quit] 07:13 -!- dr-orlovsky [~dr-orlovs@194.230.155.196] has joined ##miniscript 07:56 -!- dr-orlovsky [~dr-orlovs@194.230.155.196] has quit [Quit: My MacBook has gone to sleep. ZZZzzz…] 08:26 -!- Davterra [~tralfaz@104.200.129.62] has joined ##miniscript 15:47 -!- hugohn [sid304114@gateway/web/irccloud.com/x-hmolkenghmotdsxv] has quit [Ping timeout: 246 seconds] 15:49 -!- schmidty [sid297174@gateway/web/irccloud.com/x-kkwzljthzwlpiijv] has quit [Ping timeout: 240 seconds] 15:50 -!- RubenSomsen [sid301948@gateway/web/irccloud.com/x-sqcvwbhnlmistayr] has quit [Ping timeout: 244 seconds] 15:50 -!- elichai2 [sid212594@gateway/web/irccloud.com/x-hlzdoqcrqbwveqty] has quit [Ping timeout: 246 seconds] 15:51 -!- Aleru [sid403553@gateway/web/irccloud.com/x-khsttisuhildsbqy] has quit [Ping timeout: 260 seconds] 15:51 -!- digi_james [sid281632@gateway/web/irccloud.com/x-fjepoohrzcwjyqay] has quit [Ping timeout: 246 seconds] 15:51 -!- felixweis [sid154231@gateway/web/irccloud.com/x-suspeprsccnintnc] has quit [Ping timeout: 272 seconds] 15:52 -!- sgeisler [sid356034@gateway/web/irccloud.com/x-kuvhobnxrddtkvbj] has quit [Ping timeout: 260 seconds] 16:32 -!- sipa [~pw@gateway/tor-sasl/sipa1024] has joined ##miniscript 16:34 -!- jeremyrubin [~jr@2601:645:c200:f539:21b6:bf4:fe1d:6ab9] has joined ##miniscript 16:34 < jeremyrubin> hallo 16:34 < jeremyrubin> So I'm looking at the script: 'thresh(2,hash256(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa),s:hash256(ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff),sltv:older(10))' 16:35 < jeremyrubin> Is there a more sane way of wrapping the older clause? 16:36 < jeremyrubin> In particular the requirement to wrap with sltv seems odd -- I understand why it would produce a buggy script, but based on types what is wrong with just slv? 16:37 < jeremyrubin> ah I guess it's that older becomes v 16:39 < sipa> slv:older(10) would be "SWAP IF 0 ELSE <10> CSV VERIFY ENDIF" ? 16:39 < sipa> in one branch that puts a 0 on the stack, in the other one it doesn't 16:39 < sipa> put anything 16:39 < jeremyrubin> I guess to make my question concrete, I get why sltv:older(10) works inside of thresh, but I don't see why sltv is the only valid thing there 16:39 < jeremyrubin> My concern is that via some path a CSV could get a > 1 value on the stack 16:39 < sipa> it almost certainly isn't the only thing that works 16:40 < jeremyrubin> altv too I guess? 16:40 < sipa> for example 16:40 < sipa> but you can probably do sltvtvtvtv too :) 16:41 < jeremyrubin> I guess my question is if given a known type of Node, is there a function which can always give us a well typed wrapper for including in a thresh?\ 16:41 < sipa> yes, the policy compiler has that 16:42 < jeremyrubin> Hm I see. 16:42 < sipa> inputs come from the witness stack; i don't think anything in miniscript can result in outputs from some subexpression being fed as input to another subexpression 16:42 < sipa> and due to reliance on the MINIMALIF standardness rule, IF only accepts exactly 0 or 1 16:43 < jeremyrubin> Ah well I think that's the thing with the thresh that seemed suspect, is the argument from one thresh branch to another comes from the prior clause 16:43 < jeremyrubin> so maybe it's a composition rule, but a CSV definitely leaves the stack with an arbitrary number on it 16:43 < sipa> absolutely 16:44 < jeremyrubin> is there a reason not to make CSV B -> V and always OP_DROP it? 16:44 < jeremyrubin> just efficiency? 16:44 < sipa> yes 16:44 -!- jb55 [~jb55@gateway/tor-sasl/jb55] has joined ##miniscript 16:44 < sipa> this is accounted for by the way, the "u" type property 16:44 < sipa> guarantees that an expression will only ever leave exactly 1 on the stack (rather than an arbitrary nonzero number) for success 16:46 < sipa> many of the fragments in miniscript started off as some more complex constructions, but then simplified by breaking down into smaller parts 16:47 < jeremyrubin> gotcha. Is the rule that Base expressions are up to 4 bytes important at all? 16:47 < sipa> yes! 16:47 < jeremyrubin> What would break if CSV were to leave 6 bytes on stack? 16:48 < sipa> BOOLAND/BOOLOR won't accept those as input 16:48 < sipa> under MINIMALDATA standardness rule 16:49 < jeremyrubin> Ah I see. So presently 16:49 < jeremyrubin> Wait 16:50 < jeremyrubin> How would one construct something not type safe with or_b and older? 16:50 < sipa> as older is restricted to numbers < 2^31, you can't 16:51 < sipa> if you mean due to overflow 16:51 < jeremyrubin> ok with thing_that_overflows() 16:51 < sipa> not sure what you mean 16:51 < jeremyrubin> I guess you just put it in I see 16:51 < jeremyrubin> or_b(thing_that_overflows(), anything...) 16:51 < sipa> older(10000000000) itself won't typecheck 16:52 < jeremyrubin> BTW the websit is out of date with the latest spec :) 16:52 < jeremyrubin> might also be nice if you've the time to either update it or just add a 'out of date' banner 16:52 < jeremyrubin> Analyze a Miniscript also doesn't typecheck scripts right? 16:53 < jeremyrubin> Got a bit confused by it outputting malformed scripts 16:53 < sipa> what is out of date about it? 16:53 < jeremyrubin> I beleive multi is deprecated? 16:53 < jeremyrubin> now thresh_m 16:54 < sipa> no, the other way around 16:54 < sipa> it used to be thresh_m, it's multi now 16:54 < jeremyrubin> oh 16:54 < sipa> the site already includes https://github.com/sipa/miniscript/pull/33 16:54 < jeremyrubin> Ah I see 16:54 < sipa> i'm waiting for the rust version to also be updated 16:55 < sipa> sanket1729, andytoshi: actually, is that done? i see the related issue is closed 16:56 < jeremyrubin> I got it backwards :o 16:56 < sipa> jeremyrubin: as for your original question: https://github.com/sipa/miniscript/blob/master/compiler.cpp#L345L352 16:56 < jeremyrubin> I pulled in https://github.com/bitcoin/bitcoin/pull/17975 to have python bindings, but it definitely has some bugs in it 16:57 < sipa> for every subexpression it tries all those things (recursively, even, i think) to produce differently typed equivalent expressions 16:57 < jeremyrubin> that sounds hardcore 16:58 < sipa> THIS IS MINISPARTA 16:58 < jeremyrubin> heh 16:59 < jeremyrubin> I cannot understand this code at all haha 17:00 < sipa> that's unsurprising :) 17:00 < sipa> it has many levels of abstractions 17:00 < sipa> and the algorithm conceptually isn't that easy either 17:01 < sipa> it's a combination of top-down recursive descent and bottom-up dynamic programming 17:01 < jeremyrubin> It might be a worthwhile exercise to make a python policy compiler. I found the python miniscript impl intimidating at first but was able to understand it after an hour or so 17:02 < sipa> that'd be cool 17:02 < jeremyrubin> Then again that runs the risk of someone actually using it 17:02 < jeremyrubin> Like I am right now 17:02 < jeremyrubin> BTW is this bug indeed a bug? https://github.com/bitcoin/bitcoin/pull/17975#discussion_r449902553 17:03 < sipa> yeah, i think so 17:03 < jeremyrubin> My general impression, btw, after getting familiar with Miniscript is that Miniscript itself is not generally meant to be directly used? That's why there's policy lang correct? Is it reasonable to describe policy as miniscript+type inference? 17:04 < jeremyrubin> Is there an example of something you would want to do in miniscript that cannot be done in policy? 17:04 < sipa> i think of miniscript as a framework for reasoning about scripts 17:05 < sipa> which has some internal representation, including a textual form, so it can be embedded in descriptors 17:05 < sipa> which is confusingly also called miniscript, but really should be called "descriptors" (as miniscript support is integrated) 17:05 < sipa> s/as/after/ 17:06 < sipa> i think the policy compiler is just one example of what can be done with it, and not even the most important one 17:06 < sipa> the fact that it allows signing arbitrary (miniscript compatible) scripts is so incredibly useful, i think 17:07 < sipa> and that part doesn't need a compiler, or a concept of policies, or even a textual representation at all 17:07 < jeremyrubin> Yes descriptors are great 17:08 < jeremyrubin> I guess for context I have been trying to make a compiler that outputs miniscript stuff, and it seems like miniscript is too low level of an output format even for a compiler because I don't really care about wanting to figure out what wrapper expressions make an older clause compatible, I just want to plug it in. 17:08 < jeremyrubin> The descriptor level is fine though. 17:08 -!- helo [~helo@unaffiliated/helo] has joined ##miniscript 17:08 < sipa> you can probably compile to policy, and use an existing miniscript compiler to get descriptors out of it 17:08 < jeremyrubin> Yeah 17:09 < jeremyrubin> That's probably the correct thing to do 17:09 < sipa> but the big difference between the two is that the policy -> descriptor compilation is not 1-to-1 17:09 < sipa> a smarter compiler could come up with a better translation 17:09 < jeremyrubin> Ah interesting, yes 17:09 < sipa> also auxiliary information like probabilities of various branches affect the output 17:09 < jeremyrubin> I have the same issue 17:10 < sipa> so we needed an unambiguous representation that maps 1-to-1 with the scripts itself 17:10 < jeremyrubin> But I think that per version these compilers should aim to be deterministic 17:10 < jeremyrubin> So you can at least re-generate contracts from seeds 17:10 < sipa> i think it's better to have a decompiler that can match an existing script against an intended policy 17:11 < jeremyrubin> I would agree if p2sh/segwit/taproot weren't a thing 17:11 < jeremyrubin> that the compiled object is hashed up means reversing is not typically possible from address 17:11 < sipa> nobody should ever try to do anything with addresses anyway 17:12 < jeremyrubin> I agree, but I just meant generally 17:12 < sipa> if you're participating, you'd be given a descriptor, or a PSBT, or some other encoding that conveys the actual scripts anyway 17:12 < jeremyrubin> it is nice to be able to embed the compiler inside of a replicated state machine 17:12 < jeremyrubin> One reason is because of cut-through for protocols, both parties can compile given the state delta for example 17:12 < sipa> i don't think relying on reproducibility of the policy->descriptor form is a good idea; it's inherently limited, and doesn't compose well 17:13 < sipa> but if you're given the descriptor form, you can analyse that it does what you want 17:13 < jeremyrubin> I'll noodle on it. If it's truly bad should do what golang did with ranges 17:13 < sipa> so store the descriptor form 17:13 < jeremyrubin> I agree, but there are cases where "just store more data" isn't a great option 17:14 < sipa> if you can store a policy, you can store its compilation :) 17:14 < sipa> it's a small constant factor larger at worst 17:15 < jeremyrubin> So this becomes an issue with CTV, where I can have a contract which expands to megabytes of stuff (but only ever a small amount on chain). 17:15 < sipa> for example, in a composable scenario, you may have some parent policy, where you permit another party to fill in an arbitrary child policy (e.g. they may have a HW wallet 2-of-3 setup themselves, which you don't care about)... it's nice that they could compile a script with whatever they want substituted in, and then you as participant can check that its matches your "policy template", without needing 17:15 < jeremyrubin> And I much prefer to store the arguments (which could be small) 17:15 < sipa> the exact same compiler 17:16 < jeremyrubin> Yeah, I agree that that is cool. 17:16 < sipa> i don't think policy vs descriptor will make much of a difference in storage costs 17:16 < sipa> or some descriptor template 17:17 < sipa> or a binary encoding of those 17:20 < jeremyrubin> So one of the challenges I was having -- and I'm aware of your position on the PR for it -- is that understanding the C++ or Rust miniscript codebases is kinda rough. I was able to add CTV in a not huge amount of time to the Python implementation. Do you have any guidance on adding something like that to the C++? Does https://github.com/sipa/miniscript/pull/33/files for example show all the locations I would basically need to 17:20 < jeremyrubin> add logic for it? 17:21 < jeremyrubin> I implemented it as OP_CTV OP_DROP and Vzfm 17:22 < sipa> go through the codebase, and add it to all the big switch case statements :) 17:23 < jeremyrubin> Do you have any opinions on what it should be named? 17:23 < sipa> no 17:23 < sipa> i'm not sure CTV is even a good match for descriptors, as you know 17:23 -!- Davterra [~tralfaz@104.200.129.62] has left ##miniscript ["Leaving"] 17:23 < sipa> though for signing logic it may be useful to have it integrated 17:24 < jeremyrubin> Yeah. I'm aware. It's useful for signing logic, and we have a few options. 17:24 < jeremyrubin> So I think you could add two types (for now) 17:24 < jeremyrubin> txtmpl and txtmpl_h 17:25 < jeremyrubin> The difference being that txtmpl stores the actual template transaction, whereas txtmpl_h stores just the hash 17:25 < jeremyrubin> But they compile to the same thing 17:26 < sipa> following the rest of miniscript's design, you should never have hashes without knowing what they expand to 17:26 < jeremyrubin> hmm 17:26 < sipa> which is why there is no pk_h that takes a hash as argument 17:26 < jeremyrubin> what about sha256(x) 17:26 < sipa> because you wouldn't be able to spend it 17:26 < jeremyrubin> is x the preimage or image 17:26 < sipa> well there the preimage is considered the secret! 17:26 < sipa> fair point 17:27 < jeremyrubin> It's also hard because for CTV you already presuppose an external tx store 17:27 < sipa> descriptors are designed to store everything someone might need to spend, except private material 17:27 < sipa> yes, that's why i think it's not a very good match 17:27 < jeremyrubin> Because if my TX has outputs which expand to other CTV steps you need their descriptors too :/ 17:27 < jeremyrubin> Recursive descriptors? 17:28 < jeremyrubin> In theory I can output the tx and then have descriptors-for-outputs 17:28 < jeremyrubin> Then it would be conceptually cleaner 17:29 < jeremyrubin> But I agree they may not be a great match, but it seems like the alternative (completely separate ecosystem and toolchain for ctv related things) isn't so great either 17:29 < jeremyrubin> and you still need to put the CTV hashes inside your policies even if everything lives at another layer 17:29 < sipa> i can't imagine that there will effectively be a pretty much separate ecosystem anyway 17:29 < sipa> *won't 17:29 < sipa> in descriptorland everything is nicely noninteractive 17:30 < jeremyrubin> Hm? 17:30 < jeremyrubin> CTV is very noninteractive not sure I follow 17:30 < sipa> i guess that's true 17:30 < sipa> i shouldn't call it noninteractivity 17:30 < jeremyrubin> that's why it works nicely, I can give you a program and then you can compile the thing and send it to me 17:30 < jeremyrubin> And I can reverse it and check it complies 17:31 < jeremyrubin> But reversing more complex logic is hard so I just re-compile for that and check same output... 17:32 < jeremyrubin> I think it's reasonable to layer it tho. Script descriptors continue to be per-tx only and then transaction level data should live at tx-descriptors level 17:33 < sipa> right 17:33 < jeremyrubin> That favors the txtmpl_h version even though it's a non-secret thing 17:33 -!- shesek [~shesek@5.22.128.126] has joined ##miniscript 17:33 < shesek> does miniscript policy only allow to produce scripts that are encumbered by a public key? that is, no hashlock-encumbered-only "I want my bitcoins stolen by anyone seeing the tx before it confirms" transactions, or gifting bitcoins to a future miner with a timelock-only encumberment (a la the CSV-based fidelity bond scheme)? 17:34 < sipa> miniscript supports hashlocks and timelocks 17:34 < shesek> it seems that http://bitcoin.sipa.be/miniscript/ is not willing to accept policies that don't have some pk() that will necessarily be used, i.e. and(pk(a),after(3)) is working but or(pk(a),after(3)) (or just a plain after) is not 17:34 < sipa> yes, you need a public key 17:34 < sipa> otherwise the result is insecure 17:35 < jeremyrubin> I think I can just add CTV to that list 17:35 < sipa> it won't accept policies that permit spending without any public key 17:35 < jeremyrubin> PK or CTV 17:35 < jeremyrubin> shesek: that would solve that issue 17:35 < shesek> for some cases "insecure" might be intended, like CSV fidelity bonds 17:36 < sipa> shesek: there are too many edge cases to consider there 17:36 < jeremyrubin> shesek: I agree it's a bit odd because some things (e.g., anchor outputs) you don't care who spends maybe 17:36 < shesek> aka "proof of gifting to some random future miner" 17:36 < shesek> but yes, okay, I see the rational, just wanted to understand if this was intentional 17:36 * jeremyrubin is surprised nobody has paid fiedlity bonds to miners 150 years from now with 100x mining rewards 17:36 < shesek> does rust-miniscript implement a similar limitation? 17:37 < jeremyrubin> maybe makes sense to make it a flag for safe mode or smth 17:37 < shesek> btw, miniscript does accept these, its just the policy language that doesn't 17:39 < jeremyrubin> Hmm 17:39 < shesek> so hmm, another question. I'm a bit confused about the notation for the hash fragments. do they always take a literal "H" as their argument, even if there are multiple of them? and later it matches the preimages according to the order? 17:39 < jeremyrubin> sipa: what happens if you try to reverse them into policies from rust 17:39 < jeremyrubin> rust: compile older(100) 17:39 < sipa> policy and miniscript all support unsafe scripts 17:39 < sipa> they just don't have all type properties you may want 17:39 < jeremyrubin> c++: reverse(rust compile older(100)) 17:39 < sipa> the website is just a demonstration 17:40 < jeremyrubin> BTW is the rust or c++ impl more "canonical"? I'm guessing c++? 17:40 < sipa> that'll depend on who you ask, i'm sure :p 17:40 * sipa obviously says the C++ on 17:40 < sipa> shesek: the website is just a demonstration; it has some hacks to make it a bit easier to use 17:41 < jeremyrubin> shesek: my understanding is that the order is correct on the hints? 17:41 < sipa> the H thing is just convenience... we could add an H1 H2 H3... 17:41 < jeremyrubin> Maybe I'm over indexing on how the python impl is 17:41 < jeremyrubin> But you output a list of all satisfactions and they have some data you need to filter 17:42 < jeremyrubin> e.g., the OLDER clauses should not have any witness elem 17:42 < jeremyrubin> But the other things seem to be in correct order? 17:42 < sipa> i don't know what you're talking about 17:43 < jeremyrubin> Can I output a list of all the templates of possible witnesses? 17:43 < sipa> if you implement that 17:43 < jeremyrubin> Ah. It's implemented in the python so I thought it was something common 17:43 < sipa> i don't think my C++ code has something like that, but it'd be easy to add 17:44 < jeremyrubin> yeah my format presently is to generate all transactions with all possible witnesses as a big list 17:44 < jeremyrubin> And then I send that to my frontend client 17:45 < jeremyrubin> Which then collapses them down to a single tx with multiple witnesses 17:45 < sipa> that may be intractible 17:45 < sipa> *intractable 17:45 < jeremyrubin> all possible witness templates, ignoring malleability I guess 17:45 < jeremyrubin> I guess it's kinda stupid but it works for now 17:45 < shesek> sipa, so the H is just a website thing, not part of the miniscript syntax itself? can I see an example of using miniscript from cpp somewhere? ideally something that constructs a miniscript, identifies the hashes and and satisfies their preimage requirements 17:46 < sipa> shesek: stop thinking of miniscript as a product :) 17:46 < shesek> I'm also a bit confused about how pk() accepts a name. is that name something that you can later give a value for from the cpp api? 17:46 < sipa> it's a framework to reason about scripts 17:46 < sipa> if it doesn't do what you want, change it 17:46 < jeremyrubin> shesek: I think you pass in hex 17:46 < shesek> rust-miniscript appears to accept pubkeys directly in addition to names 17:47 < sipa> it'll be integrated into various things, and they'll accept whatever makes sense there 17:47 < shesek> sipa, its actually exactly what I'm doing :p 17:47 < sipa> there is no "syntax" really, or only at an abstract level 17:47 < sipa> even in the implementation 17:47 < sipa> in the compiler, miniscript code is instantiated with string names as public key type 17:47 < shesek> I'm writing a tiny language that compiles to miniscript, with support for variables to break down complex expressions, functions to extract reusable functionality, and infix operators for and/or 17:48 < sipa> in signing logic, keys are hash160's 17:48 < sipa> in descriptors, keys are descriptor key expressions 17:48 < jeremyrubin> shesek: want to contribute to my language which does that :) 17:48 < jeremyrubin> working on getting better miniscript support 17:49 < jeremyrubin> probably has a lot of the things you want already 17:49 < jeremyrubin> sipa: also happy to show you, but I figure you're busy -- if you come on saturday I'll be doing the VR meetup tho 17:49 < sipa> yeah, sorry, already way too many things on my todo list :) 17:49 * sipa should get back to them 17:50 < shesek> jeremyrubin, well, I already have a semi working version :) 17:51 < shesek> here's what that looks like, these currently compile (both examples are equivalent): https://gist.github.com/shesek/bb45b716520f462970153947463f0a9f 17:51 < shesek> jeremyrubin, I would definitely be very interested to see what you're working 17:51 < jeremyrubin> Ah cool! 17:52 < jeremyrubin> Yeah so my approach is much more simple, I just embed it as a DSL in python 17:52 < jeremyrubin> So then all of the programming-y stuff can be handled as normal python functions 17:52 < jeremyrubin> but the language is more oriented at the txn level 17:53 < jeremyrubin> if you come to the VR meetup on sat (or youtube it) I'll give a presentation on how it works more fully 17:53 < jeremyrubin> sipa: thanks for answering all my questions! 17:53 < shesek> I'm doing this with rust, using lalrpop for parsing, with a simple runtime and scoping system that I built 17:56 < shesek> I'm considering naming this minis or minsc, anyone has any thoughts on what has a nicer ring to it? 17:56 < jeremyrubin> i wouldn't name it as a prefix of miscript as that might be ambiguous for people 18:04 < shesek> sipa, I would love to hear what you think about this project, do you find this useful or unnecessary for the complexity level of typical miniscripts? are there any features that you'd like to see in higher level compile-to-miniscript languages? anything you would do differently compared to that example I posted? 18:05 < sipa> shesek: i'm more interested in improving the low-level side of things 18:06 < shesek> I see, alright 18:06 < sipa> before there are useful projects that actually work with miniscript and things like generic scripts i don't think there is that much need for things on top 18:06 < sipa> but i don't want to discourage you from going cool stuff! 18:10 < shesek> you definitely won't, I'm having fun working on this regardless :-) its my first attempt at writing a small programming language that I can proclaim as "working" (abandoned a couple other attempts many years ago, not writing a parser from scratch this time helped) 18:12 < shesek> not trying to make it python-like indentation-based and free of semicolons also simplified the parser a bunch 18:22 < shesek> does anyone have any interesting, relatively complex miniscript examples to share? 18:23 < jeremyrubin> Happy to generate plenty for you :) 18:24 < shesek> that would be great :-) 18:26 < shesek> just looking for some examples to play with, try writing them in minis/minsc and see that they compile as expected, and maybe find some inspiration for other features that I could add to make things easier 18:31 < jeremyrubin> Here's some random ones from some compiler output 18:31 < jeremyrubin> https://gist.github.com/42e505b09775eb079cd0f81ab086c3e9 18:31 < sipa> we have a grammar for generating random policies 18:35 < sipa> hmm, i wonder where it went 18:38 < shesek> jeremyrubin, thanks 18:44 < shesek> how about some real-world use cases? maybe some vault scheme? 19:22 -!- shesek [~shesek@5.22.128.126] has quit [Read error: Connection reset by peer] 19:22 -!- shesek [~shesek@5.22.128.126] has joined ##miniscript 19:34 < jeremyrubin> So I guess what's not obvious in these examples is that these are generated from vaults where I stubbed out the CTV's with signatures :) 19:37 < jeremyrubin> Let me make them more interesting by preserving locktimes 19:41 < jeremyrubin> sipa: is it correct that after/older pass unadultered locktimes/sequences through? 20:00 < jeremyrubin> shesek: preserved locktime data, this makes them more vault like https://gist.github.com/ca69c6d5ceb32e90323b29f7bc518fc0 20:13 < sanket1729> jeremyrubin: We had a slight change in miniscript by introducing aliases. https://github.com/sipa/miniscript/pull/33 . 20:15 < jeremyrubin> sanket1729: maybe something you can help with; I'd like to just link against either the C++ or Rust lib in python 20:16 < sanket1729> Sorry, I just installed sapio and did not look into details, so I am unsure what is it exactly that you require. 20:17 < sanket1729> Do you require a policy -> miniscript compiler? or Miniscript <-> bitcoin Script decoding/encoding? 20:17 < jeremyrubin> Ah. 20:18 < jeremyrubin> So currently I'm using Miniscript, but should probably switch to Policy -> miniscript. Then would also want Miniscript <-> Bitcoin Script, but -> is more important for now 20:21 < sanket1729> Awesome, I can help 20:22 < jeremyrubin> I also need to add CTV to the compiler, but I think I know how to do that more or less 20:24 < sanket1729> what's CTV? Some new op-code? 20:24 < jeremyrubin> Yes, from BIP-119 20:24 < jeremyrubin> It probably makes sense longer term to add a new type to the compiler that represents B-under-4-bytes for ctv. Can also do that but it's way more code. 20:25 < jeremyrubin> Otherwise you do CTV DROP so it implements Vz 20:27 < sanket1729> B already has 4 bytes in it 20:28 < sanket1729> it is the same for CSV/ CTLV. 20:28 < jeremyrubin> Yes CTV's arg is 32 bytes 20:28 < sanket1729> Ah, I see 20:28 < jeremyrubin> which means it can't implement B 20:29 < jeremyrubin> So the thing to do would be to implement a new type which represents a dirty stack item that should be dropped I guess? 20:29 < jeremyrubin> Or just drop it 20:31 < sanket1729> Dropping it and making it Vz seems like the easiest way, though sometimes might result in a (sligtly) inefficient compilation. 20:31 < jeremyrubin> I don't think the complexity is worth it, but it would be nice to save the byte if there's a clean way of not requiring drop. But I think all types are guaranteed currently to be <= 4bytes? 20:31 < jeremyrubin> yeah 20:31 < jeremyrubin> I guess it needs to be dropped at *some* point unless it's the only thing 20:33 < sanket1729> In some cases like for a v version of `or(CTV(hash), B_expr)`, we can take the verify outside. 20:33 < sanket1729> But yes, it can easily go complicated if we aim for optimal compilation 20:34 < jeremyrubin> yeah TBH the older/after not getting dropped is kinda weird 20:34 < sanket1729> yes, in hindsight that added a lot complications to the compiler code. 20:34 < jeremyrubin> I don't really fully get why you'd ever want and_b(older(x), after(y)) 20:35 < jeremyrubin> And it seems like a bug that v:older(10) -> 10 CSV VERIFY and not 10 CSV DROP or something (altho both fine) 20:36 < sanket1729> There are other scenarios where carrying out the verify outside is helpful. for example and(pk,or(pk,after(10)) 20:36 < jeremyrubin> because I don't even thing and_b(older(x), after(y)) is ever better than and_v(v:older(x), v:after(y)) 20:37 < sanket1729> in the second part of the and, you can take the verify outside. 20:38 < sanket1729> and_v(pk_k(A),or_i(after(10), pk(B))) 20:38 < jeremyrubin> and(pk,or(pk,after(10)) -> and_v(pk, or_i(pk, after(10)) I think makes better code than the or_b version? 20:40 < jeremyrubin> or maybe not? IF pk checksigverify ELSE 10 after DROP END v.s. pk checksig 10 after BOOLOR VERIFY 20:40 < jeremyrubin> I guess the benefit is that the or_b elides the drop? 20:42 < jeremyrubin> that makes sense i guess 20:43 < jeremyrubin> fg 20:43 < jeremyrubin> oops 20:45 < sanket1729> At a high level, the benefit only kicks with when you can take the v: outside. or_i(v:B,v:B) to v:or_i(V,V). Similar to the `K` type where you can take the outside `c:` and apply to or(K,K). 20:47 < jeremyrubin> that makes sense 21:57 -!- midnight [~midnight@unaffiliated/midnightmagic] has joined ##miniscript 21:57 < midnight> :-o it *does* exist. 21:57 * midnight sits down