Update miniscript to version 1.0
This commit is contained in:
parent
123984e99d
commit
4a51d50e1f
@ -7,10 +7,9 @@ authors = ["Riccardo Casatta <riccardo@casatta.it>", "Alekos Filini <alekos.fili
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
log = "^0.4"
|
log = "^0.4"
|
||||||
bitcoin = { version = "0.23", features = ["use-serde"] }
|
bitcoin = { version = "0.23", features = ["use-serde"] }
|
||||||
miniscript = { version = "0.12" }
|
miniscript = { version = "1.0" }
|
||||||
serde = { version = "^1.0", features = ["derive"] }
|
serde = { version = "^1.0", features = ["derive"] }
|
||||||
serde_json = { version = "^1.0" }
|
serde_json = { version = "^1.0" }
|
||||||
base64 = "^0.11"
|
|
||||||
|
|
||||||
# Optional dependencies
|
# Optional dependencies
|
||||||
sled = { version = "0.31.0", optional = true }
|
sled = { version = "0.31.0", optional = true }
|
||||||
@ -19,6 +18,7 @@ reqwest = { version = "0.10", optional = true, features = ["json"] }
|
|||||||
tokio = { version = "0.2", optional = true, features = ["rt-core"] }
|
tokio = { version = "0.2", optional = true, features = ["rt-core"] }
|
||||||
futures = { version = "0.3", optional = true }
|
futures = { version = "0.3", optional = true }
|
||||||
clap = { version = "2.33", optional = true }
|
clap = { version = "2.33", optional = true }
|
||||||
|
base64 = { version = "^0.11", optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
minimal = []
|
minimal = []
|
||||||
@ -27,7 +27,7 @@ default = ["key-value-db", "electrum"]
|
|||||||
electrum = ["electrum-client"]
|
electrum = ["electrum-client"]
|
||||||
esplora = ["reqwest", "futures", "tokio"]
|
esplora = ["reqwest", "futures", "tokio"]
|
||||||
key-value-db = ["sled"]
|
key-value-db = ["sled"]
|
||||||
cli-utils = ["clap"]
|
cli-utils = ["clap", "base64"]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
lazy_static = "1.4"
|
lazy_static = "1.4"
|
||||||
@ -41,6 +41,7 @@ name = "repl"
|
|||||||
required-features = ["cli-utils"]
|
required-features = ["cli-utils"]
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "psbt"
|
name = "psbt"
|
||||||
|
required-features = ["cli-utils"]
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "parse_descriptor"
|
name = "parse_descriptor"
|
||||||
|
|
||||||
|
@ -240,7 +240,7 @@ pub fn add_global_flags<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
|
|||||||
.value_name("SERVER:PORT")
|
.value_name("SERVER:PORT")
|
||||||
.help("Sets the Electrum server to use")
|
.help("Sets the Electrum server to use")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.default_value("tn.not.fyi:55001"),
|
.default_value("ssl://electrum.blockstream.info:60002"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("proxy")
|
Arg::with_name("proxy")
|
||||||
|
@ -10,7 +10,9 @@ use bitcoin::util::bip32::{DerivationPath, ExtendedPrivKey, Fingerprint};
|
|||||||
use bitcoin::util::psbt::PartiallySignedTransaction as PSBT;
|
use bitcoin::util::psbt::PartiallySignedTransaction as PSBT;
|
||||||
use bitcoin::{PrivateKey, PublicKey, Script};
|
use bitcoin::{PrivateKey, PublicKey, Script};
|
||||||
|
|
||||||
pub use miniscript::{Descriptor, Miniscript, MiniscriptKey, Terminal};
|
pub use miniscript::{
|
||||||
|
Descriptor, Legacy, Miniscript, MiniscriptKey, ScriptContext, Segwitv0, Terminal,
|
||||||
|
};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@ -182,13 +184,28 @@ impl ExtendedDescriptor {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn derive_with_miniscript(
|
pub fn derive_with_miniscript_legacy(
|
||||||
&self,
|
&self,
|
||||||
miniscript: Miniscript<PublicKey>,
|
miniscript: Miniscript<PublicKey, Legacy>,
|
||||||
) -> Result<DerivedDescriptor, Error> {
|
) -> Result<DerivedDescriptor, Error> {
|
||||||
let derived_desc = match self.internal {
|
let derived_desc = match self.internal {
|
||||||
Descriptor::Bare(_) => Descriptor::Bare(miniscript),
|
Descriptor::Bare(_) => Descriptor::Bare(miniscript),
|
||||||
Descriptor::Sh(_) => Descriptor::Sh(miniscript),
|
Descriptor::Sh(_) => Descriptor::Sh(miniscript),
|
||||||
|
_ => return Err(Error::CantDeriveWithMiniscript),
|
||||||
|
};
|
||||||
|
|
||||||
|
// if !self.same_structure(&derived_desc) {
|
||||||
|
// Err(Error::CantDeriveWithMiniscript)
|
||||||
|
// } else {
|
||||||
|
Ok(derived_desc)
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn derive_with_miniscript_segwit_v0(
|
||||||
|
&self,
|
||||||
|
miniscript: Miniscript<PublicKey, Segwitv0>,
|
||||||
|
) -> Result<DerivedDescriptor, Error> {
|
||||||
|
let derived_desc = match self.internal {
|
||||||
Descriptor::Wsh(_) => Descriptor::Wsh(miniscript),
|
Descriptor::Wsh(_) => Descriptor::Wsh(miniscript),
|
||||||
Descriptor::ShWsh(_) => Descriptor::ShWsh(miniscript),
|
Descriptor::ShWsh(_) => Descriptor::ShWsh(miniscript),
|
||||||
_ => return Err(Error::CantDeriveWithMiniscript),
|
_ => return Err(Error::CantDeriveWithMiniscript),
|
||||||
@ -219,13 +236,13 @@ impl ExtendedDescriptor {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(wit_script) = &psbt.inputs[input_index].witness_script {
|
if let Some(wit_script) = &psbt.inputs[input_index].witness_script {
|
||||||
self.derive_with_miniscript(Miniscript::parse(wit_script)?)
|
self.derive_with_miniscript_segwit_v0(Miniscript::parse(wit_script)?)
|
||||||
} else if let Some(p2sh_script) = &psbt.inputs[input_index].redeem_script {
|
} else if let Some(p2sh_script) = &psbt.inputs[input_index].redeem_script {
|
||||||
if p2sh_script.is_v0_p2wpkh() {
|
if p2sh_script.is_v0_p2wpkh() {
|
||||||
// wrapped p2wpkh
|
// wrapped p2wpkh
|
||||||
get_pk_from_partial_sigs().map(|pk| Descriptor::ShWpkh(*pk))
|
get_pk_from_partial_sigs().map(|pk| Descriptor::ShWpkh(*pk))
|
||||||
} else {
|
} else {
|
||||||
self.derive_with_miniscript(Miniscript::parse(p2sh_script)?)
|
self.derive_with_miniscript_legacy(Miniscript::parse(p2sh_script)?)
|
||||||
}
|
}
|
||||||
} else if let Some(utxo) = psbt.get_utxo_for(input_index) {
|
} else if let Some(utxo) = psbt.get_utxo_for(input_index) {
|
||||||
if utxo.script_pubkey.is_p2pkh() {
|
if utxo.script_pubkey.is_p2pkh() {
|
||||||
@ -236,7 +253,7 @@ impl ExtendedDescriptor {
|
|||||||
get_pk_from_partial_sigs().map(|pk| Descriptor::Wpkh(*pk))
|
get_pk_from_partial_sigs().map(|pk| Descriptor::Wpkh(*pk))
|
||||||
} else {
|
} else {
|
||||||
// try as bare script
|
// try as bare script
|
||||||
self.derive_with_miniscript(Miniscript::parse(&utxo.script_pubkey)?)
|
self.derive_with_miniscript_legacy(Miniscript::parse(&utxo.script_pubkey)?)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(Error::MissingDetails)
|
Err(Error::MissingDetails)
|
||||||
|
@ -9,7 +9,7 @@ use bitcoin::secp256k1::Secp256k1;
|
|||||||
use bitcoin::util::bip32::Fingerprint;
|
use bitcoin::util::bip32::Fingerprint;
|
||||||
use bitcoin::PublicKey;
|
use bitcoin::PublicKey;
|
||||||
|
|
||||||
use miniscript::{Descriptor, Miniscript, Terminal};
|
use miniscript::{Descriptor, Miniscript, ScriptContext, Terminal};
|
||||||
|
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use log::{debug, error, info, trace};
|
use log::{debug, error, info, trace};
|
||||||
@ -482,7 +482,11 @@ impl Policy {
|
|||||||
Ok(Some(policy))
|
Ok(Some(policy))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn satisfy(&mut self, _satisfier: &PSBTSatisfier, _desc_node: &Terminal<PublicKey>) {
|
pub fn satisfy<Ctx: ScriptContext>(
|
||||||
|
&mut self,
|
||||||
|
_satisfier: &PSBTSatisfier,
|
||||||
|
_desc_node: &Terminal<PublicKey, Ctx>,
|
||||||
|
) {
|
||||||
//self.satisfaction = self.item.satisfy(satisfier, desc_node);
|
//self.satisfaction = self.item.satisfy(satisfier, desc_node);
|
||||||
//self.contribution += &self.satisfaction;
|
//self.contribution += &self.satisfaction;
|
||||||
}
|
}
|
||||||
@ -606,7 +610,7 @@ fn signature_key_from_string(key: Option<&Box<dyn Key>>) -> Option<Policy> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MiniscriptExtractPolicy for Miniscript<String> {
|
impl<Ctx: ScriptContext> MiniscriptExtractPolicy for Miniscript<String, Ctx> {
|
||||||
fn extract_policy(
|
fn extract_policy(
|
||||||
&self,
|
&self,
|
||||||
lookup_map: &BTreeMap<String, Box<dyn Key>>,
|
lookup_map: &BTreeMap<String, Box<dyn Key>>,
|
||||||
@ -614,7 +618,7 @@ impl MiniscriptExtractPolicy for Miniscript<String> {
|
|||||||
Ok(match &self.node {
|
Ok(match &self.node {
|
||||||
// Leaves
|
// Leaves
|
||||||
Terminal::True | Terminal::False => None,
|
Terminal::True | Terminal::False => None,
|
||||||
Terminal::Pk(pubkey) => signature_from_string(lookup_map.get(pubkey)),
|
Terminal::PkK(pubkey) => signature_from_string(lookup_map.get(pubkey)),
|
||||||
Terminal::PkH(pubkey_hash) => signature_key_from_string(lookup_map.get(pubkey_hash)),
|
Terminal::PkH(pubkey_hash) => signature_key_from_string(lookup_map.get(pubkey_hash)),
|
||||||
Terminal::After(value) => {
|
Terminal::After(value) => {
|
||||||
let mut policy: Policy = SatisfiableItem::AbsoluteTimelock { value: *value }.into();
|
let mut policy: Policy = SatisfiableItem::AbsoluteTimelock { value: *value }.into();
|
||||||
@ -648,7 +652,7 @@ impl MiniscriptExtractPolicy for Miniscript<String> {
|
|||||||
Terminal::Hash160(hash) => {
|
Terminal::Hash160(hash) => {
|
||||||
Some(SatisfiableItem::HASH160Preimage { hash: *hash }.into())
|
Some(SatisfiableItem::HASH160Preimage { hash: *hash }.into())
|
||||||
}
|
}
|
||||||
Terminal::ThreshM(k, pks) => {
|
Terminal::Multi(k, pks) => {
|
||||||
Policy::make_multisig(pks.iter().map(|s| lookup_map.get(s)).collect(), *k)?
|
Policy::make_multisig(pks.iter().map(|s| lookup_map.get(s)).collect(), *k)?
|
||||||
}
|
}
|
||||||
// Identities
|
// Identities
|
||||||
@ -706,10 +710,12 @@ impl MiniscriptExtractPolicy for Descriptor<String> {
|
|||||||
| Descriptor::Pkh(pubkey)
|
| Descriptor::Pkh(pubkey)
|
||||||
| Descriptor::Wpkh(pubkey)
|
| Descriptor::Wpkh(pubkey)
|
||||||
| Descriptor::ShWpkh(pubkey) => Ok(signature_from_string(lookup_map.get(pubkey))),
|
| Descriptor::ShWpkh(pubkey) => Ok(signature_from_string(lookup_map.get(pubkey))),
|
||||||
Descriptor::Bare(inner)
|
Descriptor::Bare(inner) | Descriptor::Sh(inner) => {
|
||||||
| Descriptor::Sh(inner)
|
Ok(inner.extract_policy(lookup_map)?)
|
||||||
| Descriptor::Wsh(inner)
|
}
|
||||||
| Descriptor::ShWsh(inner) => Ok(inner.extract_policy(lookup_map)?),
|
Descriptor::Wsh(inner) | Descriptor::ShWsh(inner) => {
|
||||||
|
Ok(inner.extract_policy(lookup_map)?)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user