ElementsProject / elements-miniscript

Creative Commons Zero v1.0 Universal
11 stars 14 forks source link

Covenant extension & "Error: All spend paths must require a signature" error #80

Open louisinger opened 5 months ago

louisinger commented 5 months ago

given the following taproot descriptor, using CovExt:

eltr(
    02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e,
    {
        and_v(
            v:spk_eq(out_spk(0), 5120d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e),
            v:value_eq(
              010000000000000000,
              out_value(0)
            )
        ),
        and_v(
            v:pk(02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e), 
            older(512)
        )
    }
)

returns

Error: All spend paths must require a signature

does it mean that introspection only paths are not allowed ?

apoelstra commented 5 months ago

Yes, though I believe you can override this using the parse_with_ext API. (I don't see a way to parse descriptors with extensions, only Miniscripts, which I guess is a gap in our API.)

It would be nice if we could allow introspection-only paths like this but in general they continue to be malleability vectors. Like, in your example if somebody was spending those coins in a transaction with no other inputs, then anybody could modify the locktime, add more inputs, etc. This is not great for the network since it can lead to inconsistent mempools and wasted bandwidth, and might also cause trouble for your wallet/protocol.

louisinger commented 5 months ago

It would be nice if we could allow introspection-only paths like this but in general they continue to be malleability vectors. Like, in your example if somebody was spending those coins in a transaction with no other inputs, then anybody could modify the locktime, add more inputs, etc. This is not great for the network since it can lead to inconsistent mempools and wasted bandwidth, and might also cause trouble for your wallet/protocol.

Make sense but, in my example, we could add more introspection statements verifying all other parts of the transaction (number of inputs and outputs, locktimes etc..). It seems that we could avoid (or reduce?) malleability with more introspections or a signature is the only way ?

apoelstra commented 5 months ago

It seems that we could avoid (or reduce?) malleability with more introspections or a signature is the only way ?

No, you're right. If you constrain all the outputs of the transaction (and I guess, the sequence/locktime/version) then that should prevent all malleability. Except perhaps "somebody adds another input, sending its entire amount to fees".

I wouldn't mind extending our type-checking logic to understand that "fully constrained transactions should count as having a signature". Though it feels a bit ad-hoc. In general we aren't sure how we should be reasoning about covenant-laden Miniscripts.

sanket1729 commented 5 months ago

@louisinger You can use these indirectly by using from_str_insane APIs for getting the Miniscript structure. And then using the descriptor APIs to construct a new descriptor. Refer to example below for details.

https://github.com/BlockstreamResearch/options/blob/36a77175919101393b49f1211732db762cc7dfc1/src/options_lib/src/cov_scripts.rs#L87-L90