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