From 315e7e0b4b373d7175f21a48ff6480b6e919a2c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BF=97=E5=AE=87?= Date: Thu, 20 Jul 2023 08:17:27 +0800 Subject: [PATCH] fix: rm duplicate `bdk_tmp_plan` module --- nursery/tmp_plan/bdk_tmp_plan/Cargo.toml | 13 - nursery/tmp_plan/bdk_tmp_plan/README.md | 3 - nursery/tmp_plan/bdk_tmp_plan/src/lib.rs | 436 ------------------ .../tmp_plan/bdk_tmp_plan/src/plan_impls.rs | 323 ------------- .../tmp_plan/bdk_tmp_plan/src/requirements.rs | 218 --------- nursery/tmp_plan/bdk_tmp_plan/src/template.rs | 76 --- 6 files changed, 1069 deletions(-) delete mode 100644 nursery/tmp_plan/bdk_tmp_plan/Cargo.toml delete mode 100644 nursery/tmp_plan/bdk_tmp_plan/README.md delete mode 100644 nursery/tmp_plan/bdk_tmp_plan/src/lib.rs delete mode 100644 nursery/tmp_plan/bdk_tmp_plan/src/plan_impls.rs delete mode 100644 nursery/tmp_plan/bdk_tmp_plan/src/requirements.rs delete mode 100644 nursery/tmp_plan/bdk_tmp_plan/src/template.rs diff --git a/nursery/tmp_plan/bdk_tmp_plan/Cargo.toml b/nursery/tmp_plan/bdk_tmp_plan/Cargo.toml deleted file mode 100644 index c2d615df..00000000 --- a/nursery/tmp_plan/bdk_tmp_plan/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "bdk_tmp_plan" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -bdk_chain = { path = "../../../crates/chain", version = "0.3.1", features = ["miniscript"] } - -[features] -default = ["std"] -std = [] diff --git a/nursery/tmp_plan/bdk_tmp_plan/README.md b/nursery/tmp_plan/bdk_tmp_plan/README.md deleted file mode 100644 index 70cc100d..00000000 --- a/nursery/tmp_plan/bdk_tmp_plan/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Temporary planning module - -A temporary place to hold the planning module until https://github.com/rust-bitcoin/rust-miniscript/pull/481 is merged and released diff --git a/nursery/tmp_plan/bdk_tmp_plan/src/lib.rs b/nursery/tmp_plan/bdk_tmp_plan/src/lib.rs deleted file mode 100644 index a64d4492..00000000 --- a/nursery/tmp_plan/bdk_tmp_plan/src/lib.rs +++ /dev/null @@ -1,436 +0,0 @@ -#![allow(unused)] -#![allow(missing_docs)] -//! A spending plan or *plan* for short is a representation of a particular spending path on a -//! descriptor. This allows us to analayze a choice of spending path without producing any -//! signatures or other witness data for it. -//! -//! To make a plan you provide the descriptor with "assets" like which keys you are able to use, hash -//! pre-images you have access to, the current block height etc. -//! -//! Once you've got a plan it can tell you its expected satisfaction weight which can be useful for -//! doing coin selection. Furthermore it provides which subset of those keys and hash pre-images you -//! will actually need as well as what locktime or sequence number you need to set. -//! -//! Once you've obstained signatures, hash pre-images etc required by the plan, it can create a -//! witness/script_sig for the input. -use bdk_chain::{bitcoin, collections::*, miniscript}; -use bitcoin::{ - blockdata::{locktime::LockTime, transaction::Sequence}, - hashes::{hash160, ripemd160, sha256}, - secp256k1::Secp256k1, - util::{ - address::WitnessVersion, - bip32::{DerivationPath, Fingerprint, KeySource}, - taproot::{LeafVersion, TapBranchHash, TapLeafHash}, - }, - EcdsaSig, SchnorrSig, Script, TxIn, Witness, -}; -use miniscript::{ - descriptor::{InnerXKey, Tr}, - hash256, DefiniteDescriptorKey, Descriptor, DescriptorPublicKey, ScriptContext, ToPublicKey, -}; - -pub(crate) fn varint_len(v: usize) -> usize { - bitcoin::VarInt(v as u64).len() as usize -} - -mod plan_impls; -mod requirements; -mod template; -pub use requirements::*; -pub use template::PlanKey; -use template::TemplateItem; - -#[derive(Clone, Debug)] -enum TrSpend { - KeySpend, - LeafSpend { - script: Script, - leaf_version: LeafVersion, - }, -} - -#[derive(Clone, Debug)] -enum Target { - Legacy, - Segwitv0 { - script_code: Script, - }, - Segwitv1 { - tr: Tr, - tr_plan: TrSpend, - }, -} - -impl Target {} - -#[derive(Clone, Debug)] -/// A plan represents a particular spending path for a descriptor. -/// -/// See the module level documentation for more info. -pub struct Plan { - template: Vec>, - target: Target, - set_locktime: Option, - set_sequence: Option, -} - -impl Default for Target { - fn default() -> Self { - Target::Legacy - } -} - -#[derive(Clone, Debug, Default)] -/// Signatures and hash pre-images that can be used to complete a plan. -pub struct SatisfactionMaterial { - /// Schnorr signautres under their keys - pub schnorr_sigs: BTreeMap, - /// ECDSA signatures under their keys - pub ecdsa_sigs: BTreeMap, - /// SHA256 pre-images under their images - pub sha256_preimages: BTreeMap>, - /// hash160 pre-images under their images - pub hash160_preimages: BTreeMap>, - /// hash256 pre-images under their images - pub hash256_preimages: BTreeMap>, - /// ripemd160 pre-images under their images - pub ripemd160_preimages: BTreeMap>, -} - -impl Plan -where - Ak: Clone, -{ - /// The expected satisfaction weight for the plan if it is completed. - pub fn expected_weight(&self) -> usize { - let script_sig_size = match self.target { - Target::Legacy => unimplemented!(), // self - // .template - // .iter() - // .map(|step| { - // let size = step.expected_size(); - // size + push_opcode_size(size) - // }) - // .sum() - Target::Segwitv0 { .. } | Target::Segwitv1 { .. } => 1, - }; - let witness_elem_sizes: Option> = match &self.target { - Target::Legacy => None, - Target::Segwitv0 { .. } => Some( - self.template - .iter() - .map(|step| step.expected_size()) - .collect(), - ), - Target::Segwitv1 { tr, tr_plan } => { - let mut witness_elems = self - .template - .iter() - .map(|step| step.expected_size()) - .collect::>(); - - if let TrSpend::LeafSpend { - script, - leaf_version, - } = tr_plan - { - let control_block = tr - .spend_info() - .control_block(&(script.clone(), *leaf_version)) - .expect("must exist"); - witness_elems.push(script.len()); - witness_elems.push(control_block.size()); - } - - Some(witness_elems) - } - }; - - let witness_size: usize = match witness_elem_sizes { - Some(elems) => { - varint_len(elems.len()) - + elems - .into_iter() - .map(|elem| varint_len(elem) + elem) - .sum::() - } - None => 0, - }; - - script_sig_size * 4 + witness_size - } - - pub fn requirements(&self) -> Requirements { - match self.try_complete(&SatisfactionMaterial::default()) { - PlanState::Complete { .. } => Requirements::default(), - PlanState::Incomplete(requirements) => requirements, - } - } - - pub fn try_complete(&self, auth_data: &SatisfactionMaterial) -> PlanState { - let unsatisfied_items = self - .template - .iter() - .filter(|step| match step { - TemplateItem::Sign(key) => { - !auth_data.schnorr_sigs.contains_key(&key.descriptor_key) - } - TemplateItem::Hash160(image) => !auth_data.hash160_preimages.contains_key(image), - TemplateItem::Hash256(image) => !auth_data.hash256_preimages.contains_key(image), - TemplateItem::Sha256(image) => !auth_data.sha256_preimages.contains_key(image), - TemplateItem::Ripemd160(image) => { - !auth_data.ripemd160_preimages.contains_key(image) - } - TemplateItem::Pk { .. } | TemplateItem::One | TemplateItem::Zero => false, - }) - .collect::>(); - - if unsatisfied_items.is_empty() { - let mut witness = self - .template - .iter() - .flat_map(|step| step.to_witness_stack(&auth_data)) - .collect::>(); - match &self.target { - Target::Segwitv0 { .. } => todo!(), - Target::Legacy => todo!(), - Target::Segwitv1 { - tr_plan: TrSpend::KeySpend, - .. - } => PlanState::Complete { - final_script_sig: None, - final_script_witness: Some(Witness::from_vec(witness)), - }, - Target::Segwitv1 { - tr, - tr_plan: - TrSpend::LeafSpend { - script, - leaf_version, - }, - } => { - let spend_info = tr.spend_info(); - let control_block = spend_info - .control_block(&(script.clone(), *leaf_version)) - .expect("must exist"); - witness.push(script.clone().into_bytes()); - witness.push(control_block.serialize()); - - PlanState::Complete { - final_script_sig: None, - final_script_witness: Some(Witness::from_vec(witness)), - } - } - } - } else { - let mut requirements = Requirements::default(); - - match &self.target { - Target::Legacy => { - todo!() - } - Target::Segwitv0 { .. } => { - todo!() - } - Target::Segwitv1 { tr, tr_plan } => { - let spend_info = tr.spend_info(); - match tr_plan { - TrSpend::KeySpend => match &self.template[..] { - [TemplateItem::Sign(ref plan_key)] => { - requirements.signatures = RequiredSignatures::TapKey { - merkle_root: spend_info.merkle_root(), - plan_key: plan_key.clone(), - }; - } - _ => unreachable!("tapkey spend will always have only one sign step"), - }, - TrSpend::LeafSpend { - script, - leaf_version, - } => { - let leaf_hash = TapLeafHash::from_script(&script, *leaf_version); - requirements.signatures = RequiredSignatures::TapScript { - leaf_hash, - plan_keys: vec![], - } - } - } - } - } - - let required_signatures = match requirements.signatures { - RequiredSignatures::Legacy { .. } => todo!(), - RequiredSignatures::Segwitv0 { .. } => todo!(), - RequiredSignatures::TapKey { .. } => return PlanState::Incomplete(requirements), - RequiredSignatures::TapScript { - plan_keys: ref mut keys, - .. - } => keys, - }; - - for step in unsatisfied_items { - match step { - TemplateItem::Sign(plan_key) => { - required_signatures.push(plan_key.clone()); - } - TemplateItem::Hash160(image) => { - requirements.hash160_images.insert(image.clone()); - } - TemplateItem::Hash256(image) => { - requirements.hash256_images.insert(image.clone()); - } - TemplateItem::Sha256(image) => { - requirements.sha256_images.insert(image.clone()); - } - TemplateItem::Ripemd160(image) => { - requirements.ripemd160_images.insert(image.clone()); - } - TemplateItem::Pk { .. } | TemplateItem::One | TemplateItem::Zero => { /* no requirements */ - } - } - } - - PlanState::Incomplete(requirements) - } - } - - /// Witness version for the plan - pub fn witness_version(&self) -> Option { - match self.target { - Target::Legacy => None, - Target::Segwitv0 { .. } => Some(WitnessVersion::V0), - Target::Segwitv1 { .. } => Some(WitnessVersion::V1), - } - } - - /// The minimum required locktime height or time on the transaction using the plan. - pub fn required_locktime(&self) -> Option { - self.set_locktime.clone() - } - - /// The minimum required sequence (height or time) on the input to satisfy the plan - pub fn required_sequence(&self) -> Option { - self.set_sequence.clone() - } - - /// The minmum required transaction version required on the transaction using the plan. - pub fn min_version(&self) -> Option { - if let Some(_) = self.set_sequence { - Some(2) - } else { - Some(1) - } - } -} - -/// The returned value from [`Plan::try_complete`]. -pub enum PlanState { - /// The plan is complete - Complete { - /// The script sig that should be set on the input - final_script_sig: Option