Good morning Billy,

> Hi ZmnSCPxj,
>
> >  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
>
> I'm not suggesting that you wouldn't have to pay a fee for it. You'd pay a 
> fee for it as normal, so there's no DOS vector. Doesn't adding extra witness 
> data do what would be needed here? Eg simply adding extra data onto the 
> witness script that will remain unconsumed after successful execution of the 
> script?

I think we would want to have a cleanstack rule at some point (do not remember 
out-of-hand if Taproot already enforces one).

So now being nice to the network is *more* costly?
That just *dis*incentivizes jet usage.

> > how do new jets get introduced?
>
> In scenario A, new jets get introduced by being added to bitcoin software as 
> basically relay rules. 
>
> > If a new jet requires coordinated deployment over the network, then you 
> > might as well just softfork and be done with it.
>
> It would not need a coordinated deployment. However, the more nodes that 
> supported that jet, the more efficient using it would be for the network. 
>
> > 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?
>
> When a new version of bitcoin comes out, people generally upgrade to it 
> eventually. No coordination is needed. 100% of the network need not support a 
> jet. Just some critical mass to get some benefit. 

How large is the critical mass needed?

If you use witness to transport jet information across non-upgraded nodes, then 
that disincentivizes use of jets and you can only incentivize jets by softfork, 
so you might as well just get a softfork.

If you have no way to transport jet information from an upgraded through a 
non-upgraded back to an upgraded node, then I think you need a fairly large 
buy-in from users before non-upgraded nodes are rare enough that relay is not 
much affected, and if the required buy-in is large enough, you might as well 
softfork.

> > Having a static lookup table is better since you can pattern-match on 
> > strings of specific, static length
>
> Sorry, better than what exactly? 

Than using a dynamic lookup table, which is how I understood your previous 
email about "scripts in the 1000 past blocks".

> > How does the unupgraded-to-upgraded boundary work?
> <snip>
> When the non-jet aware node sends this to a jet-aware node, that node would 
> see the extra items on the stack after script execution, and would interpret 
> them as an OP_JET call specifying that OP_JET should replace the witness 
> items starting at index 0 with `1b5f03cf  OP_JET`. It does this and then 
> sends that along to the next hop.

It would have to validate as well that the SCRIPT sub-section matches the jet, 
else I could pretend to be a non-jet-aware node and give you a SCRIPT 
sub-section that does not match the jet and would cause your validation to 
diverge from other nodes.

Adler32 seems a bit short though, it seems to me that it may lead to two 
different SCRIPT subsections hashing to the same hash.

Suppose I have two different node softwares.
One uses a particular interpretation for a particular Adler32 hash.
The other uses a different interpretation.
If we are not careful, if these two jet-aware software talk to each other, they 
will ban each other from the network and cause a chainsplit.
Since the Bitcoin software is open source, nothing prevents anyone from using a 
different SCRIPT subsection for a particular Adler32 hash if they find a 
collision and can somehow convince people to run their modified software.

> In order to support this without a soft fork, this extra otherwise 
> unnecessary data would be needed, but for jets that represent long scripts, 
> the extra witness data could be well worth it (for the network). 
>
> However, this extra data would be a disincentive to do transactions this way, 
> even when its better for the network. So it might not be worth doing it this 
> way without a soft fork. But with a soft fork to upgrade nodes to support an 
> OP_JET opcode, the extra witness data can be removed (replaced with 
> out-of-band script fragment transmission for nodes that don't support a 
> particular jet). 

Which is why I pointed out that each individual jet may very well require a 
softfork, or enough buy-in that you might as well just softfork.

> One interesting additional thing that could be done with this mechanism is to 
> add higher-order function ability to jets, which could allow nodes to add 
> OP_FOLD or similar functions as a jet without requiring additional soft 
> forks.  Hypothetically, you could imagine a jet script that uses an OP_LOOP 
> jet be written as follows:
>
> 5             # Loop 5 times
> 1             # Loop the next 1 operation
> 3c1g14ad 
> OP_JET
> OP_ADD  # The 1 operation to loop
>
> The above would sum up 5 numbers from the stack. And while this summation jet 
> can't be represented in bitcoin script on its own (since bitcoin script can't 
> manipulate opcode calls), the jet *call* can still be represented as:
>
> OP_ADD  
> OP_ADD  
> OP_ADD  
> OP_ADD  
> OP_ADD  
>
> which means all of the above replacement functionality would work just as 
> well. 
>
> So my point here is that jets implemented in a way similar to this would give 
> a much wider range of "code as compression" possibilities than implementing a 
> single opcode like op_fold. 

Yes, that is certainly the case, and nothing really prevents us bringing 
"programming as compression" to its logical conclusion.

> > To make jets more useful, we should redesign the language so that `OP_PUSH` 
> > is not in the opcode stream, but instead, we have a separate table of 
> > constants that is attached / concatenated to the actual SCRIPT.
>
> This can already be done, right? You just have to redesign the script to 
> consume and swap/rot around the data in the right way to separate them out 
> from the main script body. 

Yes, but that implies additional operations (and execution overhead), 
increasing the costs to use jets, which makes it even less palatable to use 
jets, *in addition to* the witness hack disincentivizing jets.

So I would suggest that, if we were to seriously pursue jets, we should really 
replace most of the `OP_PUSH` opcodes with variants that look up in a static 
table at the start, before the executable script body.
I.e. opcodes 0x01 to 0x4e instead mean "push contents of `c1` to `c78` from the 
constants table", and have aliases `a` through `z` for `c1` to `c26`, etc.
That way, replacing the `OP_PUSH` is shorter in the actual SCRIPT (instead of a 
bunch of stack manipulations) and hopefully the overhead of the constants table 
can be kept low.

In particular, this helps jets compose more easily; if we want a SCRIPT that 
incorporates an existing jet, we do not have to manipulate the stack in a way 
that the existing jet expects, we just load the proper data into the constants 
table.

Or something, anyway.
This seems a fair amount of complexity here.

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

Reply via email to