rust-bitcoin / rust-miniscript

Support for Miniscript and Output Descriptors for rust-bitcoin
Creative Commons Zero v1.0 Universal
349 stars 136 forks source link

How to infer a descriptor #675

Open yancyribbens opened 6 months ago

yancyribbens commented 6 months ago

From what I can tell, to infer a descriptor requires creating an Interpreter, then calling .inferred_descriptor(). However, to build an interpreter, requires a BitcoinKey which is private not to mention the innner module and stack module which are also private. Is it possible to expose some interface to allow inferring a descriptor?

sanket1729 commented 6 months ago

Interpreter::from_txdata is the only way to create one. The main use for interpreter is looking at a transaction in blockchain "inferring" the descriptor from it.

sanket1729 commented 6 months ago

Inferring descriptors by itself requires the complete knowledge of spending transaction. You cannot infer a p2wsh witness script by only looking at the hash.

yancyribbens commented 6 months ago

I see. We've discussed this in other threads, but I was looking to compute the satisfaction weight of an individual TxIn, not a Transaction. It sounds like this isn't something Miniscript is designed to accomplish if I'm understanding right.

sanket1729 commented 6 months ago

@yancyribbens , it is actually the opposite. You don't "infer" a descriptor.

The interpreter module is not for this case. Yes, You know it beforehand

but I was looking to compute the satisfaction weight of an individual TxIn

We have methods to compute the satisfaction_weight of each Descriptor, but users needs to know the descriptor beforehand. It is not something they obtain from the blockchain. As a simple example, consider two multisig scripts (2-of-3 and 100-of-150). Both of them appear as a single 32 byte WSH script on the blockchain, but satisfaction costs of each of them are massively different.

This is where output descriptors come in. For the two of three, you would have a descriptor wsh(2,pk(A), pk(B), pk(C)) and other descriptor would be wsh(100,pk(A1)....pk(A150)) .

Taking a guess here, maybe what you need is a simple BIP 84 descriptor like wpkh(xpub/84/0/*) or something similar?

You can read about output descriptors: bip380

apoelstra commented 6 months ago

@sanket1729 I think we ought to have a method to infer a descriptor, or at least these lengths, from an appropriately-populated PSBT. I think that's a reasonable thing that people would want to do.

I'm on the fence about promoting Interpreter::from_txdata more. Sometimes it's useful if you've architected yourself into a corner but I guess we shouldn't be promoting that kind of worklflow.

sanket1729 commented 6 months ago

I'm on the fence about promoting Interpreter::from_txdata more. Sometimes it's useful if you've architected yourself into a corner but I guess we shouldn't be promoting that kind of worklflow.

Agreed. This is only meant for block-explorers. And should not be used for most other use-cases. There is already a private get_descriptor method on psbt, but I don't think that is what @yancyribbens needs. Even before creating a psbt, we need to decide on fees and do coin selection. This is where we need some for descriptors.

I think we ought to have a method to infer a descriptor, or at least these lengths, from an appropriately-populated PSBT. I think that's a reasonable thing that people would want to do.

I think what @yancyribbens actually needs a lengths of descriptors. He can create a descriptor like wpkh(pk(A)) and use the miniscript APIs to get the length without actually knowing the concrete keys.

yancyribbens commented 6 months ago

I think what @yancyribbens actually needs a lengths of descriptors. He can create a descriptor like wpkh(pk(A)) and use the miniscript APIs to get the length without actually knowing the concrete keys.

@sanket1729 I'm looking to calculate the size of an input before adding it to a transaction. For example, given 3 inputs of different types and unlock scripts, how many weight units would each input be. I'm only looking for the weight that a TxIn might contribute to a transaction regardless of the size of the descriptor.