Re: [bitcoin-dev] CTV Meeting #5 Agenda (Tuesday, March 7th, 12:00 PT)

2022-03-07 Thread Jeremy Rubin via bitcoin-dev
* Tuesday, March 8th.

I think Noon PT == 8pm UTC?

but dont trust me i cant even tell what day is what.
--
@JeremyRubin 


On Mon, Mar 7, 2022 at 6:50 PM Jeremy Rubin 
wrote:

> Hi all,
>
> There will be a CTV meeting tomorrow at noon PT. Agenda below:
>
> 1) Sapio Taproot Support Update / Request for Review (20 Minutes)
> - Experimental support for Taproot merged on master
> https://github.com/sapio-lang/sapio
> 2) Transaction Sponsoring v.s CPFP/RBF (20 Minutes)
> -
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-February/019879.html
> -
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-September/018168.html
> 3) Jamesob's Non-Recursive Vaults Post (20 minutes)
> -
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-March/020067.html
> 4) What the heck is everyone talking about on the mailing list all of the
> sudden (30 minutes)
> - EVICT, TLUV, FOLD, Lisp, OP_ANNEX, Drivechain Covenants, Jets, Etc
> 5) Q (30 mins)
>
> Best,
>
> Jeremy
>
>
> --
> @JeremyRubin 
>
___
bitcoin-dev mailing list
bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev


Re: [bitcoin-dev] bitcoin scripting and lisp

2022-03-07 Thread ZmnSCPxj via bitcoin-dev
Good morning aj et al.,


> > They're radically different approaches and
> > it's hard to see how they mix. Everything in lisp is completely sandboxed,
> > and that functionality is important to a lot of things, and it's really
> > normal to be given a reveal of a scriptpubkey and be able to rely on your
> > parsing of it.
>
> The above prevents combining puzzles/solutions from multiple coin spends,
> but I don't think that's very attractive in bitcoin's context, the way
> it is for chia. I don't think it loses much else?

But cross-input signature aggregation is a nice-to-have we want for Bitcoin, 
and, to me, cross-input sigagg is not much different from cross-input 
puzzle/solution compression.

For example you might have multiple HTLCs, with mostly the same code except for 
details like who the acceptor and offerrer are, exact hash, and timelock, and 
you could claim multiple HTLCs in a single tx and feed the details separately 
but the code for the HTLC is common to all of the HTLCs.
You do not even need to come from the same protocol if multiple protocols use 
the same code for implementing HTLC.

> > > There's two ways to think about upgradability here; if someday we want
> > > to add new opcodes to the language -- perhaps something to validate zero
> > > knowledge proofs or calculate sha3 or use a different ECC curve, or some
> > > way to support cross-input signature aggregation, or perhaps it's just
> > > that some snippets are very widely used and we'd like to code them in
> > > C++ directly so they validate quicker and don't use up as much block
> > > weight. One approach is to just define a new version of the language
> > > via the tapleaf version, defining new opcodes however we like.
> > > A nice side benefit of sticking with the UTXO model is that the soft fork
> > > hook can be that all unknown opcodes make the entire thing automatically
> > > pass.
>
> I don't think that works well if you want to allow the spender (the
> puzzle solution) to be able to use opcodes introduced in a soft-fork
> (eg, for graftroot-like behaviour)?

This does not apply to current Bitcoin since we no longer accept a SCRIPT from 
the spender, we now have a witness stack.
However, once we introduce opcodes that allow recursive covenants, it seems 
this is now a potential footgun if the spender can tell the puzzle SCRIPT to 
load some code that will then be used in the *next* UTXO created, and *then* 
the spender can claim it.

Hmmm Or maybe not?
If the spender can already tell the puzzle SCRIPT to send the funds to a SCRIPT 
that is controlled by the spender, the spender can already tell the puzzle 
SCRIPT to forward the funds to a pubkey the spender controls.
So this seems to be more like "do not write broken SCRIPTs"?

> > > > - serialization seems to be a bit verbose -- 100kB of serialized clvm
> > > >    code from a random block gzips to 60kB; optimising the serialization
> > > >    for small lists, and perhaps also for small literal numbers might be
> > > >    a feasible improvement; though it's not clear to me how frequently
> > > >    serialization size would be the limiting factor for cost versus
> > > >    execution time or memory usage.
> > > > A lot of this is because there's a hook for doing compression at the 
> > > > consensus layer which isn't being used aggressively yet. That one has 
> > > > the downside that the combined cost of transactions can add up very 
> > > > nonlinearly, but when you have constantly repeated bits of large 
> > > > boilerplate it gets close and there isn't much of an alternative. That 
> > > > said even with that form of compression maxxed out it's likely that 
> > > > gzip could still do some compression but that would be better done in 
> > > > the database and in wire protocol formats rather than changing the 
> > > > format which is hashed at the consensus layer.
> > > > How different is this from "jets" as proposed in Simplicity?
>
> Rather than a "transaction" containing "inputs/outputs", chia has spend
> bundles that spend and create coins; and spend bundles can be merged
> together, so that a block only has a single spend bundle. That spend
> bundle joins all the puzzles (the programs that, when hashed match
> the scriptPubKey) and solutions (scriptSigs) for the coins being spent
> together.
>
> I /think/ the compression hook would be to allow you to have the puzzles
> be (re)generated via another lisp program if that was more efficient
> than just listing them out. But I assume it would be turtles, err,
> lisp all the way down, no special C functions like with jets.

Eh, you could use Common LISP or a recent-enough RnRS Scheme to write a 
cryptocurrency node software, so "special C function" seems to overprivilege 
C...
I suppose the more proper way to think of this is that jets are *equivalent to* 
some code in the hosted language, and have an *efficient implementation* in the 
hosting language.
In this view, the current OG Bitcoin SCRIPT is the hosted 

[bitcoin-dev] CTV Meeting #5 Agenda (Tuesday, March 7th, 12:00 PT)

2022-03-07 Thread Jeremy Rubin via bitcoin-dev
Hi all,

There will be a CTV meeting tomorrow at noon PT. Agenda below:

1) Sapio Taproot Support Update / Request for Review (20 Minutes)
- Experimental support for Taproot merged on master
https://github.com/sapio-lang/sapio
2) Transaction Sponsoring v.s CPFP/RBF (20 Minutes)
-
https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-February/019879.html
-
https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-September/018168.html
3) Jamesob's Non-Recursive Vaults Post (20 minutes)
-
https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-March/020067.html
4) What the heck is everyone talking about on the mailing list all of the
sudden (30 minutes)
- EVICT, TLUV, FOLD, Lisp, OP_ANNEX, Drivechain Covenants, Jets, Etc
5) Q (30 mins)

Best,

Jeremy


--
@JeremyRubin 
___
bitcoin-dev mailing list
bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev


Re: [bitcoin-dev] bitcoin scripting and lisp

2022-03-07 Thread Anthony Towns via bitcoin-dev
On Sun, Mar 06, 2022 at 10:26:47PM -0800, Bram Cohen via bitcoin-dev wrote:
> > After looking into it, I actually think chia lisp [1] gets pretty much all
> > the major design decisions pretty much right. There are obviously a few
> > changes needed given the differences in design between chia and bitcoin:
> Bitcoin uses the UTXO model as opposed to Chia's Coin Set model. While
> these are close enough that it's often explained as Chia uses the UTXO
> model but that isn't technically true. Relevant to the above comment is
> that in the UTXO model transactions get passed to a scriptpubkey and it
> either assert fails or it doesn't, while in the coin set model each puzzle
> (scriptpubkey) gets run and either assert fails or returns a list of extra
> conditions it has, possibly including timelocks and creating new coins,
> paying fees, and other things.

One way to match the way bitcoin do things, you could have the "list of
extra conditions" encoded explicitly in the transaction via the annex,
and then check the extra conditions when the script is executed.

> If you're doing everything from scratch it's cleaner to go with the coin
> set model, but retrofitting onto existing Bitcoin it may be best to leave
> the UTXO model intact and compensate by adding a bunch more opcodes which
> are special to parsing Bitcoin transactions. The transaction format itself
> can be mostly left alone but to enable some of the extra tricks (mostly
> implementing capabilities) it's probably a good idea to make new
> conventions for how a transaction can have advisory information which
> specifies which of the inputs to a transaction is the parent of a specific
> output and also info which is used for communication between the UTXOs in a
> transaction.

I think the parent/child coin relationship is only interesting when
"unrelated" spends can assert that the child coin is being created -- ie
things along the lines of the "transaction sponsorship" proposal. My
feeling is that complicates the mempool a bit much, so is best left for
later, if done at all.

(I think the hard part of managing the extra conditions is mostly
in keeping it efficient to manage the mempool and construct the most
profitable blocks/bundles, rather than where the data goes)

> But one could also make lisp-generated UTXOs be based off transactions
> which look completely trivial and have all their important information be
> stored separately in a new vbytes area. That works but results in a bit of
> a dual identity where some coins have both an old style id and a new style
> id which gunks up what

We've already got a txid and a wtxid, adding more ids seems best avoided
if possible...

> > Pretty much all the opcodes in the first section are directly from chia
> > lisp, while all the rest are to complete the "bitcoin" functionality.
> > The last two are extensions that are more food for thought than a real
> > proposal.
> Are you thinking of this as a completely alternative script format or an
> extension to bitcoin script?

As an alternative to tapscript, so when constructing the merkle tree of
scripts for a taproot address, you could have some of those scripts be
in tapscript as it exists today with OP_CHECKSIG etc, and others could
be in lisp. (You could then have an entirely lisp-based sub-merkle-tree
of lisp fragments via sha256tree or similar of course)

> They're radically different approaches and
> it's hard to see how they mix. Everything in lisp is completely sandboxed,
> and that functionality is important to a lot of things, and it's really
> normal to be given a reveal of a scriptpubkey and be able to rely on your
> parsing of it.

The above prevents combining puzzles/solutions from multiple coin spends,
but I don't think that's very attractive in bitcoin's context, the way
it is for chia. I don't think it loses much else?

> > There's two ways to think about upgradability here; if someday we want
> > to add new opcodes to the language -- perhaps something to validate zero
> > knowledge proofs or calculate sha3 or use a different ECC curve, or some
> > way to support cross-input signature aggregation, or perhaps it's just
> > that some snippets are very widely used and we'd like to code them in
> > C++ directly so they validate quicker and don't use up as much block
> > weight. One approach is to just define a new version of the language
> > via the tapleaf version, defining new opcodes however we like.
> A nice side benefit of sticking with the UTXO model is that the soft fork
> hook can be that all unknown opcodes make the entire thing automatically
> pass.

I don't think that works well if you want to allow the spender (the
puzzle solution) to be able to use opcodes introduced in a soft-fork
(eg, for graftroot-like behaviour)?

> Chia's approach to transaction fees is essentially identical to Bitcoin's
> although a lot fewer things in the ecosystem support fees due to a lack of
> having needed it yet. I don't think mempool issues have much to 

Re: [bitcoin-dev] CTV vaults in the wild

2022-03-07 Thread ZmnSCPxj via bitcoin-dev
Good morning Antoine,

> Hi James,
>
> Interesting to see a sketch of a CTV-based vault design !
>
> I think the main concern I have with any hashchain-based vault design is the 
> immutability of the flow paths once the funds are locked to the root vault 
> UTXO. By immutability, I mean there is no way to modify the 
> unvault_tx/tocold_tx transactions and therefore recover from transaction 
> fields
> corruption (e.g a unvault_tx output amount superior to the root vault UTXO 
> amount) or key endpoints compromise (e.g the cold storage key being stolen).
>
> Especially corruption, in the early phase of vault toolchain deployment, I 
> believe it's reasonable to expect bugs to slip in affecting the output amount 
> or relative-timelock setting correctness (wrong user config, miscomputation 
> from automated vault management, ...) and thus definitively freezing the 
> funds. Given the amounts at stake for which vaults are designed, errors are 
> likely to be far more costly than the ones we see in the deployment of 
> payment channels.
>
> It might be more conservative to leverage a presigned transaction data design 
> where every decision point is a multisig. I think this design gets you the 
> benefit to correct or adapt if all the multisig participants agree on. It 
> should also achieve the same than a key-deletion design, as long as all
> the vault's stakeholders are participating in the multisig, they can assert 
> that flow paths are matching their spending policy.

Have not looked at the actual vault design, but I observe that Taproot allows 
for a master key (which can be an n-of-n, or a k-of-n with setup (either 
expensive or trusted, but I repeat myself)) to back out of any contract.

This master key could be an "even colder" key that you bury in the desert to be 
guarded over by generations of Fremen riding giant sandworms until the Bitcoin 
Path prophesied by the Kwisatz Haderach, Satoshi Nakamoto, arrives.

> Of course, relying on presigned transactions comes with higher assumptions on 
> the hardware hosting the flow keys. Though as hashchain-based vault design 
> imply "secure" key endpoints (e.g ), as a vault user you're 
> still encumbered with the issues of key management, it doesn't relieve you to 
> find trusted hardware. If you want to avoid multiplying devices to trust, I 
> believe flow keys can be stored on the same keys guarding the UTXOs, before 
> sending to vault custody.
>
> I think the remaining presence of trusted hardware in the vault design might 
> lead one to ask what's the security advantage of vaults compared to classic 
> multisig setup. IMO, it's introducing the idea of privileges in the coins 
> custody : you set up the flow paths once for all at setup with the highest 
> level of privilege and then anytime you do a partial unvault you don't need 
> the same level of privilege. Partial unvault authorizations can come with a 
> reduced set of verifications, at lower operational costs. That said, I think 
> this security advantage is only relevant in the context of recursive design, 
> where the partial unvault sends back the remaining funds to vault UTXO (not 
> the design proposed here).
>
> Few other thoughts on vault design, more minor points.
>
> "If Alice is watching the mempool/chain, she will see that the unvault 
> transaction has been unexpectedly broadcast,"
>
> I think you might need to introduce an intermediary, out-of-chain protocol 
> step where the unvault broadcast is formally authorized by the vault 
> stakeholders. Otherwise it's hard to qualify "unexpected", as hot key 
> compromise might not be efficiently detected.

Thought: It would be nice if Alice could use Lightning watchtowers as well, 
that would help increase the anonymity set of both LN watchtower users and 
vault users.

> "With  OP_CTV, we can ensure that the vault operation is enforced by 
> consensus itself, and the vault transaction data can be generated 
> deterministically without additional storage needs."
>
> Don't you also need the endpoint scriptPubkeys (, ), 
> the amounts and CSV value ? Though I think you can grind amounts and CSV 
> value in case of loss...But I'm not sure if you remove the critical data 
> persistence requirement, just reduce the surface.
>
> "Because we want to be able to respond immediately, and not have to dig out 
> our cold private keys, we use an additional OP_CTV to encumber the "swept" 
> coins for spending by only the cold wallet key."
>
> I think a robust vault deployment would imply the presence of a set of 
> watchtowers, redundant entities able to broadcast the cold transaction in 
> reaction to unexpected unvault. One feature which could be interesting is 
> "tower accountability", i.e knowing which tower initiated the broadcast, 
> especially if it's a faultive one. One way is to watermark the cold 
> transaction (e.g tweak nLocktime to past value). Though I believe with CTV 
> you would need as much different hashes than towers included in 

[bitcoin-dev] Jets (Was: `OP_FOLD`: A Looping Construct For Bitcoin SCRIPT)

2022-03-07 Thread ZmnSCPxj via bitcoin-dev
Good morning Billy,

Changed subject since this is only tangentially related to `OP_FOLD`.

> Let me organize my thoughts on this a little more clearly. There's a couple 
> possibilities I can think of for a jet-like system:
>
> A. We could implement jets now without a consensus change, and without 
> requiring all nodes to upgrade to new relay rules. Probably. This would give 
> upgraded nodes improved validation performance and many upgraded nodes relay 
> savings (transmitting/receiving fewer bytes). Transactions would be weighted 
> the same as without the use of jets tho.
> B. We could implement the above + lighter weighting by using a soft fork to 
> put the jets in a part of the blockchain hidden from unupgraded nodes, as you 
> mentioned. 
> C. We could implement the above + the jet registration idea in a soft fork. 
>
> For A:
>
> * Upgraded nodes query each connection for support of jets in general, and 
> which specific jets they support.
> * For a connection to another upgraded node that supports the jet(s) that a 
> transaction contains, the transaction is sent verbatim with the jet included 
> in the script (eg as some fake opcode line like 23 OP_JET, indicating to 
> insert standard jet 23 in its place). When validation happens, or when a 
> miner includes it in a block, the jet opcode call is replaced with the script 
> it represents so hashing happens in a way that is recognizable to unupgraded 
> nodes.
> * For a connection to a non-upgraded node that doesn't support jets, or an 
> upgraded node that doesn't support the particular jet included in the script, 
> the jet opcode call is replaced as above before sending to that node. In 
> addition, some data is added to the transaction that unupgraded nodes 
> propagate along but otherwise ignore. Maybe this is extra witness data, maybe 
> this is some kind of "annex", or something else. But that data would contain 
> the original jet opcode (in this example "23 OP_JET") so that when that 
> transaction data reaches an upgraded node that recognizes that jet again, it 
> can swap that back in, in place of the script fragment it represents. 
>
> I'm not 100% sure the required mechanism I mentioned of "extra ignored data" 
> exists, and if it doesn't, then all nodes would at least need to be upgraded 
> to support that before this mechanism could fully work.

I am not sure that can even be *made* to exist.
It seems to me a trivial way to launch a DDoS: Just ask a bunch of fullnodes to 
add this 1Mb of extra ignored data in this tiny 1-input-1-output transaction so 
I pay only a small fee if it confirms but the bandwidth of all fullnodes is 
wasted transmitting and then ignoring this block of data.

> But even if such a mechanism doesn't exist, a jet script could still be used, 
> but it would be clobbered by the first nonupgraded node it is relayed to, and 
> can't then be converted back (without using a potentially expensive lookup 
> table as you mentioned). 

Yes, and people still run Bitcoin Core 0.8.x.

> > If the script does not weigh less if it uses a jet, then there is no 
> > incentive for end-users to use a jet
>
> That's a good point. However, I'd point out that nodes do lots of things that 
> there's no individual incentive for, and this might be one where people 
> either altruistically use jets to be lighter on the network, or use them in 
> the hopes that the jet is accepted as a standard, reducing the cost of their 
> scripts. But certainly a direct incentive to use them is better. Honest nodes 
> can favor connecting to those that support jets.

Since you do not want a dynamic lookup table (because of the cost of lookup), 
how do new jets get introduced?
If a new jet requires coordinated deployment over the network, then you might 
as well just softfork and be done with it.
If a new jet can just be entered into some configuration file, how do you 
coordinate those between multiple users so that there *is* some benefit for 
relay?

> >if a jet would allow SCRIPT weights to decrease, upgraded nodes need to hide 
> >them from unupgraded nodes
> > we have to do that by telling unupgraded nodes "this script will always 
> > succeed and has weight 0"
>
> Right. It doesn't have to be weight zero, but that would work fine enough. 
>
> > if everybody else has not upgraded, a user of a new jet has no security.
>
> For case A, no security is lost. For case B you're right. For case C, once 
> nodes upgrade to the initial soft fork, new registered jets can take 
> advantage of relay-cost weight savings (defined by the soft fork) without 
> requiring any nodes to do any upgrading, and nodes could be further upgraded 
> to optimize the validation of various of those registered jets, but those 
> processing savings couldn't change the weighting of transactions without an 
> additional soft fork.
>
> > Consider an attack where I feed you a SCRIPT that validates trivially but 
> > is filled with almost-but-not-quite-jettable code
>
> I 

Re: [bitcoin-dev] bitcoin scripting and lisp

2022-03-07 Thread ZmnSCPxj via bitcoin-dev
Good morning Bram,

> while in the coin set model each puzzle (scriptpubkey) gets run and either 
> assert fails or returns a list of extra conditions it has, possibly including 
> timelocks and creating new coins, paying fees, and other things.

Does this mean it basically gets recursive covenants?
Or is a condition in this list of conditions written a more restrictive 
language which itself cannot return a list of conditions?


> >  - serialization seems to be a bit verbose -- 100kB of serialized clvm
> >    code from a random block gzips to 60kB; optimising the serialization
> >    for small lists, and perhaps also for small literal numbers might be
> >    a feasible improvement; though it's not clear to me how frequently
> >    serialization size would be the limiting factor for cost versus
> >    execution time or memory usage.
>
> A lot of this is because there's a hook for doing compression at the 
> consensus layer which isn't being used aggressively yet. That one has the 
> downside that the combined cost of transactions can add up very nonlinearly, 
> but when you have constantly repeated bits of large boilerplate it gets close 
> and there isn't much of an alternative. That said even with that form of 
> compression maxxed out it's likely that gzip could still do some compression 
> but that would be better done in the database and in wire protocol formats 
> rather than changing the format which is hashed at the consensus layer.

How different is this from "jets" as proposed in Simplicity?

> > Pretty much all the opcodes in the first section are directly from chia
> > lisp, while all the rest are to complete the "bitcoin" functionality.
> > The last two are extensions that are more food for thought than a real
> > proposal.
>
> Are you thinking of this as a completely alternative script format or an 
> extension to bitcoin script? They're radically different approaches and it's 
> hard to see how they mix. Everything in lisp is completely sandboxed, and 
> that functionality is important to a lot of things, and it's really normal to 
> be given a reveal of a scriptpubkey and be able to rely on your parsing of it.

I believe AJ is proposing a completely alternative format to OG Bitcoin SCRIPT.
Basically, as I understand it, nothing in the design of Tapscript versions 
prevents us from completely changing the interpretation of Tapscript bytes, and 
use a completely different language.
That is, we could designate a new Tapscript version as completely different 
from OG Bitcoin SCRIPT.


Regards,
ZmnSCPxj
___
bitcoin-dev mailing list
bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev


Re: [bitcoin-dev] `OP_FOLD`: A Looping Construct For Bitcoin SCRIPT

2022-03-07 Thread Billy Tetrud via bitcoin-dev
Let me organize my thoughts on this a little more clearly. There's a couple
possibilities I can think of for a jet-like system:

A. We could implement jets now without a consensus change, and
without requiring all nodes to upgrade to new relay rules. Probably. This
would give upgraded nodes improved validation performance and many upgraded
nodes relay savings (transmitting/receiving fewer bytes). Transactions
would be weighted the same as without the use of jets tho.
B. We could implement the above + lighter weighting by using a soft fork to
put the jets in a part of the blockchain hidden from unupgraded nodes, as
you mentioned.
C. We could implement the above + the jet registration idea in a soft fork.

For A:

* Upgraded nodes query each connection for support of jets in general, and
which specific jets they support.
* For a connection to another upgraded node that supports the jet(s) that a
transaction contains, the transaction is sent verbatim with the jet
included in the script (eg as some fake opcode line like 23 OP_JET,
indicating to insert standard jet 23 in its place). When validation
happens, or when a miner includes it in a block, the jet opcode call is
replaced with the script it represents so hashing happens in a way that is
recognizable to unupgraded nodes.
* For a connection to a non-upgraded node that doesn't support jets, or an
upgraded node that doesn't support the particular jet included in the
script, the jet opcode call is replaced as above before sending to that
node. In addition, some data is added to the transaction that unupgraded
nodes propagate along but otherwise ignore. Maybe this is extra witness
data, maybe this is some kind of "annex", or something else. But that data
would contain the original jet opcode (in this example "23 OP_JET") so that
when that transaction data reaches an upgraded node that recognizes that
jet again, it can swap that back in, in place of the script fragment it
represents.

I'm not 100% sure the required mechanism I mentioned of "extra ignored
data" exists, and if it doesn't, then all nodes would at least need to be
upgraded to support that before this mechanism could fully work. But even
if such a mechanism doesn't exist, a jet script could still be used, but it
would be clobbered by the first nonupgraded node it is relayed to, and
can't then be converted back (without using a potentially expensive lookup
table as you mentioned).

> If the script does not weigh less if it uses a jet, then there is no
incentive for end-users to use a jet

That's a good point. However, I'd point out that nodes do lots of things
that there's no individual incentive for, and this might be one where
people either altruistically use jets to be lighter on the network, or use
them in the hopes that the jet is accepted as a standard, reducing the cost
of their scripts. But certainly a direct incentive to use them is better.
Honest nodes can favor connecting to those that support jets.

>if a jet would allow SCRIPT weights to decrease, upgraded nodes need to
hide them from unupgraded nodes
> we have to do that by telling unupgraded nodes "this script will always
succeed and has weight 0"

Right. It doesn't have to be weight zero, but that would work fine enough.

> if everybody else has not upgraded, a user of a new jet has no security.

For case A, no security is lost. For case B you're right. For case C, once
nodes upgrade to the initial soft fork, new registered jets can take
advantage of relay-cost weight savings (defined by the soft fork) without
requiring any nodes to do any upgrading, and nodes could be further
upgraded to optimize the validation of various of those registered jets,
but those processing savings couldn't change the weighting of transactions
without an additional soft fork.

> Consider an attack where I feed you a SCRIPT that validates trivially but
is filled with almost-but-not-quite-jettable code

I agree a pattern-matching lookup table is probably not a great design. But
a lookup table like that is not needed for the jet registration idea. After
the necessary soft fork, there would be standard rules for which registered
jets nodes are required to keep an index of, and so the lookup table would
be a straightforward jet hash lookup rather than a pattern-matching lookup,
which wouldn't have the same DOS problems. A node would simply find a jet
opcode call like "ab38cd39e OP_JET" and just lookup ab38cd39e in its index.


On Sun, Mar 6, 2022 at 2:38 PM ZmnSCPxj  wrote:

> Good morning Billy,
>
> > Even changing the weight of a transaction using jets (ie making a script
> weigh less if it uses a jet) could be done in a similar way to how segwit
> separated the witness out.
>
> The way we did this in SegWit was to *hide* the witness from unupgraded
> nodes, who are then unable to validate using the upgraded rules (because
> you are hiding the data from them!), which is why I bring up:
>
> > > If a new jet is released but nobody else has upgraded, how bad is 

[bitcoin-dev] bitcoin scripting and lisp

2022-03-07 Thread Bram Cohen via bitcoin-dev
>
> After looking into it, I actually think chia lisp [1] gets pretty much all
> the major design decisions pretty much right. There are obviously a few
> changes needed given the differences in design between chia and bitcoin:
>
>  - having secp256k1 signatures (and curve operations), instead of
>BLS12-381 ones
>
>  - adding tx introspection instead of having bundle-oriented CREATE_COIN,
>and CREATE/ASSERT results [10]
>

Bitcoin uses the UTXO model as opposed to Chia's Coin Set model. While
these are close enough that it's often explained as Chia uses the UTXO
model but that isn't technically true. Relevant to the above comment is
that in the UTXO model transactions get passed to a scriptpubkey and it
either assert fails or it doesn't, while in the coin set model each puzzle
(scriptpubkey) gets run and either assert fails or returns a list of extra
conditions it has, possibly including timelocks and creating new coins,
paying fees, and other things.

If you're doing everything from scratch it's cleaner to go with the coin
set model, but retrofitting onto existing Bitcoin it may be best to leave
the UTXO model intact and compensate by adding a bunch more opcodes which
are special to parsing Bitcoin transactions. The transaction format itself
can be mostly left alone but to enable some of the extra tricks (mostly
implementing capabilities) it's probably a good idea to make new
conventions for how a transaction can have advisory information which
specifies which of the inputs to a transaction is the parent of a specific
output and also info which is used for communication between the UTXOs in a
transaction.

But one could also make lisp-generated UTXOs be based off transactions
which look completely trivial and have all their important information be
stored separately in a new vbytes area. That works but results in a bit of
a dual identity where some coins have both an old style id and a new style
id which gunks up what


>
>  - serialization seems to be a bit verbose -- 100kB of serialized clvm
>code from a random block gzips to 60kB; optimising the serialization
>for small lists, and perhaps also for small literal numbers might be
>a feasible improvement; though it's not clear to me how frequently
>serialization size would be the limiting factor for cost versus
>execution time or memory usage.
>

A lot of this is because there's a hook for doing compression at the
consensus layer which isn't being used aggressively yet. That one has the
downside that the combined cost of transactions can add up very
nonlinearly, but when you have constantly repeated bits of large
boilerplate it gets close and there isn't much of an alternative. That said
even with that form of compression maxxed out it's likely that gzip could
still do some compression but that would be better done in the database and
in wire protocol formats rather than changing the format which is hashed at
the consensus layer.


> Pretty much all the opcodes in the first section are directly from chia
> lisp, while all the rest are to complete the "bitcoin" functionality.
> The last two are extensions that are more food for thought than a real
> proposal.
>

Are you thinking of this as a completely alternative script format or an
extension to bitcoin script? They're radically different approaches and
it's hard to see how they mix. Everything in lisp is completely sandboxed,
and that functionality is important to a lot of things, and it's really
normal to be given a reveal of a scriptpubkey and be able to rely on your
parsing of it.


> There's two ways to think about upgradability here; if someday we want
> to add new opcodes to the language -- perhaps something to validate zero
> knowledge proofs or calculate sha3 or use a different ECC curve, or some
> way to support cross-input signature aggregation, or perhaps it's just
> that some snippets are very widely used and we'd like to code them in
> C++ directly so they validate quicker and don't use up as much block
> weight. One approach is to just define a new version of the language
> via the tapleaf version, defining new opcodes however we like.
>

A nice side benefit of sticking with the UTXO model is that the soft fork
hook can be that all unknown opcodes make the entire thing automatically
pass.


>
> The other is to use the "softfork" opcode -- chia defines it as:
>
>   (softfork cost code)
>
> though I think it would probably be better if it were
>
>   (softfork cost version code)
>

Since softfork has to date never been used that second parameter is
technically completely ignored and could be anything at all. Most likely a
convention including some kind of version information will be created the
first time it's used. Also Chia shoves total cost into blocks at the
consensus layer out of an abundance of caution although that isn't
technically necessary.

[10] [9] The CREATE/ASSERT bundling stuff is interesting; and could be
> used to achieve functionality like the 

Re: [bitcoin-dev] Annex Purpose Discussion: OP_ANNEX, Turing Completeness, and other considerations

2022-03-07 Thread Antoine Riard via bitcoin-dev
Hi Jeremy,

> I've seen some discussion of what the Annex can be used for in Bitcoin.
For
> example, some people have discussed using the annex as a data field for
> something like CHECKSIGFROMSTACK type stuff (additional authenticated
data)
> or for something like delegation (the delegation is to the annex). I think
> before devs get too excited, we should have an open discussion about what
> this is actually for, and figure out if there are any constraints to using
> it however we may please.

I think one interesting purpose of the annex is to serve as a transaction
field extension, where we assign new consensus validity rules to the annex
payloads.

One could think about new types of locks, e.g where a transaction inclusion
is constrained before the annex payload value is superior to the chain's
`ChainWork`. This could be useful in case of contentious forks, where you
want your transaction to confirm only when enough work is accumulated, and
height isn't a reliable indicator anymore.

Or a relative-timelock where the endpoint is the presence of a state number
encumbering the spent transaction. This could be useful in the context of
payment pools, where the user withdraw transactions are all encumbered by a
bip68 relative-timelock, as you don't know which one is going to confirm
first, but where you don't care about enforcement of the timelocks once the
contestation delay has played once  and no higher-state update transaction
has confirmed.

Of course, we could reuse the nSequence field for some of those new types
of locks, though we would lose the flexibility of combining multiple locks
encumbering the same input.

Another use for the annex is locating there the SIGHASH_GROUP group count
value. One advantage over placing the value as a script stack item could be
to have annex payloads interdependency validity, where other annex payloads
are reusing the group count value as part of their own semantics.

Antoine

Le ven. 4 mars 2022 à 18:22, Jeremy Rubin via bitcoin-dev <
bitcoin-dev@lists.linuxfoundation.org> a écrit :

> I've seen some discussion of what the Annex can be used for in Bitcoin.
> For example, some people have discussed using the annex as a data field for
> something like CHECKSIGFROMSTACK type stuff (additional authenticated data)
> or for something like delegation (the delegation is to the annex). I think
> before devs get too excited, we should have an open discussion about what
> this is actually for, and figure out if there are any constraints to using
> it however we may please.
>
> The BIP is tight lipped about it's purpose, saying mostly only:
>
> *What is the purpose of the annex? The annex is a reserved space for
> future extensions, such as indicating the validation costs of
> computationally expensive new opcodes in a way that is recognizable without
> knowing the scriptPubKey of the output being spent. Until the meaning of
> this field is defined by another softfork, users SHOULD NOT include annex
> in transactions, or it may lead to PERMANENT FUND LOSS.*
>
> *The annex (or the lack of thereof) is always covered by the signature and
> contributes to transaction weight, but is otherwise ignored during taproot
> validation.*
>
> *Execute the script, according to the applicable script rules[11], using
> the witness stack elements excluding the script s, the control block c, and
> the annex a if present, as initial stack.*
>
> Essentially, I read this as saying: The annex is the ability to pad a
> transaction with an additional string of 0's that contribute to the virtual
> weight of a transaction, but has no validation cost itself. Therefore,
> somehow, if you needed to validate more signatures than 1 per 50 virtual
> weight units, you could add padding to buy extra gas. Or, we might somehow
> make the witness a small language (e.g., run length encoded zeros) such
> that we can very quickly compute an equivalent number of zeros to 'charge'
> without actually consuming the space but still consuming a linearizable
> resource... or something like that. We might also e.g. want to use the
> annex to reserve something else, like the amount of memory. In general, we
> are using the annex to express a resource constraint efficiently. This
> might be useful for e.g. simplicity one day.
>
> Generating an Annex: One should write a tracing executor for a script, run
> it, measure the resource costs, and then generate an annex that captures
> any externalized costs.
>
> ---
>
> Introducing OP_ANNEX: Suppose there were some sort of annex pushing
> opcode, OP_ANNEX which puts the annex on the stack as well as a 0 or 1 (to
> differentiate annex is 0 from no annex, e.g. 0 1 means annex was 0 and 0 0
> means no annex). This would be equivalent to something based on  flag> OP_TXHASH  OP_TXHASH.
>
> Now suppose that I have a computation that I am running in a script as
> follows:
>
> OP_ANNEX
> OP_IF
> `some operation that requires annex to be <1>`
> OP_ELSE
> OP_SIZE
> 

Re: [bitcoin-dev] CTV vaults in the wild

2022-03-07 Thread Antoine Riard via bitcoin-dev
Hi James,

Interesting to see a sketch of a CTV-based vault design !

I think the main concern I have with any hashchain-based vault design is
the immutability of the flow paths once the funds are locked to the root
vault UTXO. By immutability, I mean there is no way to modify the
unvault_tx/tocold_tx transactions and therefore recover from transaction
fields
corruption (e.g a unvault_tx output amount superior to the root vault UTXO
amount) or key endpoints compromise (e.g the cold storage key being
stolen).

Especially corruption, in the early phase of vault toolchain deployment, I
believe it's reasonable to expect bugs to slip in affecting the output
amount or relative-timelock setting correctness (wrong user config,
miscomputation from automated vault management, ...) and thus definitively
freezing the funds. Given the amounts at stake for which vaults are
designed, errors are likely to be far more costly than the ones we see in
the deployment of payment channels.

It might be more conservative to leverage a presigned transaction data
design where every decision point is a multisig. I think this design gets
you the benefit to correct or adapt if all the multisig participants agree
on. It should also achieve the same than a key-deletion design, as long as
all
the vault's stakeholders are participating in the multisig, they can assert
that flow paths are matching their spending policy.

Of course, relying on presigned transactions comes with higher assumptions
on the hardware hosting the flow keys. Though as hashchain-based vault
design imply "secure" key endpoints (e.g ), as a vault user
you're still encumbered with the issues of key management, it doesn't
relieve you to find trusted hardware. If you want to avoid multiplying
devices to trust, I believe flow keys can be stored on the same keys
guarding the UTXOs, before sending to vault custody.

I think the remaining presence of trusted hardware in the vault design
might lead one to ask what's the security advantage of vaults compared to
classic multisig setup. IMO, it's introducing the idea of privileges in the
coins custody : you set up the flow paths once for all at setup with the
highest level of privilege and then anytime you do a partial unvault you
don't need the same level of privilege. Partial unvault authorizations can
come with a reduced set of verifications, at lower operational costs. That
said, I think this security advantage is only relevant in the context of
recursive design, where the partial unvault sends back the remaining funds
to vault UTXO (not the design proposed here).

Few other thoughts on vault design, more minor points.

"If Alice is watching the mempool/chain, she will see that the unvault
transaction has been unexpectedly broadcast,"

I think you might need to introduce an intermediary, out-of-chain protocol
step where the unvault broadcast is formally authorized by the vault
stakeholders. Otherwise it's hard to qualify "unexpected", as hot key
compromise might not be efficiently detected.

"With  OP_CTV, we can ensure that the vault operation is enforced by
consensus itself, and the vault transaction data can be generated
deterministically without additional storage needs."

Don't you also need the endpoint scriptPubkeys (,
), the amounts and CSV value ? Though I think you can grind
amounts and CSV value in case of loss...But I'm not sure if you remove the
critical data persistence requirement, just reduce the surface.

"Because we want to be able to respond immediately, and not have to dig out
our cold private keys, we use an additional OP_CTV to encumber the "swept"
coins for spending by only the cold wallet key."

I think a robust vault deployment would imply the presence of a set of
watchtowers, redundant entities able to broadcast the cold transaction in
reaction to unexpected unvault. One feature which could be interesting is
"tower accountability", i.e knowing which tower initiated the broadcast,
especially if it's a faultive one. One way is to watermark the cold
transaction (e.g tweak nLocktime to past value). Though I believe with CTV
you would need as much different hashes than towers included in your
unvault output (can be wrapped in a Taproot tree ofc). With presigned
transactions, tagged versions of the cold transaction are stored off-chain.

"In this implementation, we make use of anchor outputs in order to allow
mummified unvault transactions to have their feerate adjusted dynamically."

I'm not sure if the usage of anchor output is safe for any vault deployment
where the funds stakeholders do not trust each other or where the
watchtowers are not trusted. If a distrusted party can spend the anchor
output it's easy to block the RBF with a pinning.

Can we think about other criterias on which to sort vault designs ?

(I would say space efficiency is of secondary concern as we can expect
vault users as a class of on-chain space demand to be in the higher ranks
of blockspace "buying power". Though it's always 

Re: [bitcoin-dev] Annex Purpose Discussion: OP_ANNEX, Turing Completeness, and other considerations

2022-03-07 Thread Anthony Towns via bitcoin-dev
On Sat, Mar 05, 2022 at 12:20:02PM +, Jeremy Rubin via bitcoin-dev wrote:
> On Sat, Mar 5, 2022 at 5:59 AM Anthony Towns  wrote:
> > The difference between information in the annex and information in
> > either a script (or the input data for the script that is the rest of
> > the witness) is (in theory) that the annex can be analysed immediately
> > and unconditionally, without necessarily even knowing anything about
> > the utxo being spent.
> I agree that should happen, but there are cases where this would not work.
> E.g., imagine OP_LISP_EVAL + OP_ANNEX... and then you do delegation via the
> thing in the annex.
> Now the annex can be executed as a script.

You've got the implication backwards: the benefit isn't that the annex
*can't* be used as/in a script; it's that it *can* be used *without*
having to execute/analyse a script (and without even having to load the
utxo being spent).

How big a benefit that is might be debatable -- it's only a different
ordering of the work you have to do to be sure the transaction is valid;
it doesn't reduce the total work. And I think you can easily design
invalid transactions that will maximise the work required to establish
the tx is invalid, no matter what order you validate things.

> Yes, this seems tough to do without redefining checksig to allow partial
> annexes.

"Redefining checksig to allow X" in taproot means "defining a new pubkey
format that allows a new sighash that allows X", which, if it turns out
to be necessary/useful, is entirely possible.  It's not sensible to do
what you suggest *now* though, because we don't have a spec of how a
partial annex might look.

> Hence thinking we should make our current checksig behavior
> require it be 0,

Signatures already require the annex to not be present. If you personally
want to do that for every future transaction you sign off on, you
already can.

> > It seems like a good place for optimising SIGHASH_GROUP (allowing a group
> > of inputs to claim a group of outputs for signing, but not allowing inputs
> > from different groups to ever claim the same output; so that each output
> > is hashed at most once for this purpose) -- since each input's validity
> > depends on the other inputs' state, it's better to be able to get at
> > that state as easily as possible rather than having to actually execute
> > other scripts before your can tell if your script is going to be valid.
> I think SIGHASH_GROUP could be some sort of mutable stack value, not ANNEX.

The annex is already a stack value, and the SIGHASH_GROUP parameter
cannot be mutable since it will break the corresponding signature, and
(in order to ensure validating SIGHASH_GROUP signatures don't require
hashing the same output multiple times) also impacts SIGHASH_GROUP
signatures from other inputs.

> you want to be able to compute what range you should sign, and then the
> signature should cover the actual range not the argument itself.

The value that SIGHASH_GROUP proposes putting in the annex is just an
indication of whether (a) this input is using the same output group as
the previous input; or else (b) how many outputs are in this input's
output group. The signature naturally commits to that value because it's
signing all the outputs in the group anyway.

> Why sign the annex literally?

To prevent it from being third-party malleable.

When there is some meaning assigned to the annex then perhaps it will
make sense to add some more granular way of accessing it via script, but
until then, committing to the whole thing is the best option possible,
since it still allows some potential uses of the annex without having
to define a new sighash.

Note that signing only part of the annex means that you probably
reintroduce the quadratic hashing problem -- that is, with a script of
length X and an annex of length Y, you may have to hash O(X*Y) bytes
instead of O(X+Y) bytes (because every X/k bytes of the script selects
a different Y/j subset of the annex to sign).

> Why require that all signatures in one output sign the exact same digest?
> What if one wants to sign for value and another for value + change?

You can already have one signature for value and one for value+change:
use SIGHASH_SINGLE for the former, and SIGHASH_ALL for the latter.
SIGHASH_GROUP is designed for the case where the "value" goes to
multiple places.

> > > Essentially, I read this as saying: The annex is the ability to pad a
> > > transaction with an additional string of 0's
> > If you wanted to pad it directly, you can do that in script already
> > with a PUSH/DROP combo.
> You cannot, because the push/drop would not be signed and would be
> malleable.

If it's a PUSH, then it's in the tapscript and committed to by the
scriptPubKey, and not malleable.

There's currently no reason to have padding specifiable at spend time --
you know when you're writing the script whether the spender can reuse
the same signature for multiple CHECKSIG ops, because the only way to
do that is to