Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BDK breaks public keys in descriptor #792

Closed
evd0kim opened this issue Nov 1, 2022 · 6 comments
Closed

BDK breaks public keys in descriptor #792

evd0kim opened this issue Nov 1, 2022 · 6 comments
Labels
bug Something isn't working

Comments

@evd0kim
Copy link

evd0kim commented Nov 1, 2022

Descriptions
BDK compiles policy into invalid descriptor (too short public key)

This is an example of broken descriptor:

wsh(or_d(pk(027a3565454fe1b749bccaef22aff72843a9c3efefd7b16ac54537a0c23f0ec0de),and_v(v:thresh(2,pkh(dbd7a2efb12c6682dda6ddb19e6fad03dd93254a),a:pkh(b51d25d2dfe3a507db591c5a1b38f0821f3b583c),a:pkh(b0468e1c215f2ace1b7f21bdfcd2879d36b30e3f)),older(24))))#vmgy375r

To Reproduce

// This will be used by Daniela to generate the descriptor
// You don't need to use this, you're not cool enough, sorry not sorry <3
use bdk::bitcoin::hashes::hex::FromHex;
use bdk::{bitcoin, descriptor};
use bdk::descriptor::Descriptor;
use bdk::miniscript::policy::Concrete;
use bdk::miniscript::DummyKey;
use std::str::FromStr;
use std::sync::Arc;
use bdk::bitcoin::{PrivateKey, secp256k1};
use bdk::miniscript::interpreter::SatisfiedConstraint::PublicKey;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let secp256k1 = secp256k1::Secp256k1::new();
    let zengo_private_key_str = "cQhdvB3McbBJdx78VSSumqoHQiSXs75qwLptqwxSQBNBMDxafvaw";
    let zengo_private_key = PrivateKey::from_str(zengo_private_key_str).expect("Can't create private key");

    let keys = [
        // TODO: insert all the pubkeys here
        // Example: (delete both keys when inserting yours)
        "032d672a1a91cc39d154d366cd231983661b0785c7f27bc338447565844f4a6813",
        "03417129311ed34c242c012cd0a3e0b9bca0065f742d0dfb63c78083ea6a02d4d9",
        "025a687659658baeabdfc415164528065be7bcaade19342241941e556557f01e28",
    ];

    let bridge_policy = Concrete::<bitcoin::PublicKey>::from_str(&format!(
        "or(99@pk({zen_go}),1@and(older({expiry}),thresh(2,pk({bk1}),pk({bk2}),pk({bk3}))))",
        zen_go = zengo_private_key.public_key(&secp256k1),
        bk1 = keys[0],
        bk2 = keys[1],
        bk3 = keys[2],
        expiry = "24"
    )).unwrap();

    let bridge_descriptor = Descriptor::new_wsh(
        bridge_policy
            .compile()
            .expect("Policy compilation only fails on resource limits or mixed timelocks"),
    ).expect("Resource limits");

    println!("{}", bridge_descriptor);

    Ok(())
}

Expected behavior

This is an expected output I have from vanilla rust-miniscript:

"wsh(or_d(pk(027a3565454fe1b749bccaef22aff72843a9c3efefd7b16ac54537a0c23f0ec0de),and_v(v:thresh(2,pkh(032d672a1a91cc39d154d366cd231983661b0785c7f27bc338447565844f4a6813),a:pkh(03417129311ed34c242c012cd0a3e0b9bca0065f742d0dfb63c78083ea6a02d4d9),a:pkh(025a687659658baeabdfc415164528065be7bcaade19342241941e556557f01e28)),older(24))))#96dry60v"

As you may see, public keys are kept as they were provided by keys vector.

Build environment

  • BDK tag/commit: "0.23.0"
  • OS+version: Linux
  • Rust/Cargo version: Nightly
  • Rust/Cargo target: x86_64-unknown-linux-gnu
@evd0kim evd0kim added the bug Something isn't working label Nov 1, 2022
@notmandatory notmandatory moved this to Todo in BDK PM Roadmap Nov 2, 2022
@notmandatory
Copy link
Member

Thanks for reporting this, we'll look into it and I'll put it on the agenda for bitcoindevkit/.github#31.

@afilini
Copy link
Member

afilini commented Nov 3, 2022

Are you trying to load the descriptor in BDK or in a different application? Because I know miniscript changed the way they handle pkh() in the latest version (8.0), which we will be using in the upcoming BDK 0.24 release.

So essentially by using BDK 0.23 you are compiling using miniscript 7.0, and I think it may produce a descriptor that can't be loaded by miniscript 8.0.

Another thing you could try is compiling to a Concrete::<String> so that miniscript won't touch your keys at all.

@evd0kim
Copy link
Author

evd0kim commented Nov 3, 2022

You are probably right.
I didn't pay attention to such details. In addition, recently I noticed that Str and str are handled differently.
Anyway, I dropped figuring out how to work with BDK in my task and trying to figure out things with other tools. hal turned to be simpler.

@afilini afilini closed this as completed Nov 3, 2022
Repository owner moved this from Todo to Done in BDK PM Roadmap Nov 3, 2022
@notmandatory
Copy link
Member

Thanks for resolving this guys, @engenegr i'm not familiar with hal can you share a link? I'd like to understand what other similar tools are out there.

@evd0kim
Copy link
Author

evd0kim commented Nov 5, 2022

@notmandatory

https://github.com/sanket1729/hal

just handy tool. helps with functions which in Core may have longer inputs. i tried to build psbt there but in the meantime realized that it uses different PSBT type than one that I need. I have to learn a lot.

@notmandatory
Copy link
Member

Thanks! looks like a useful tool.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Archived in project
Development

No branches or pull requests

3 participants