fn spend_spendable_outputs(&self, descriptors: &[&SpendableOutputDescriptor], outputs: Vec<TxOut>, change_destination_script: Script, feerate_sat_per_1000_weight: u32, secp_ctx: &Secp256k1<All>) -> Result<Transaction, ()> {
        let mut input = Vec::new();
        let mut input_value = 0;
        let mut witness_weight = 0;
        let mut output_set = HashSet::with_capacity(descriptors.len());
        for outp in descriptors {
            match outp {
                SpendableOutputDescriptor::StaticPaymentOutput(descriptor) => {
                    input.push(TxIn {
                        previous_output: descriptor.outpoint.into_bitcoin_outpoint(),
                        script_sig: Script::new(),
                        sequence: 0,
                        witness: Vec::new(),
                    });
                    witness_weight += StaticPaymentOutputDescriptor::MAX_WITNESS_LENGTH;
                    input_value += descriptor.output.value;
                    if !output_set.insert(descriptor.outpoint) { return Err(()); }
                },
                SpendableOutputDescriptor::DelayedPaymentOutput(descriptor) => {
                    input.push(TxIn {
                        previous_output: descriptor.outpoint.into_bitcoin_outpoint(),
                        script_sig: Script::new(),
                        sequence: descriptor.to_self_delay as u32,
                        witness: Vec::new(),
                    });
                    witness_weight += DelayedPaymentOutputDescriptor::MAX_WITNESS_LENGTH;
                    input_value += descriptor.output.value;
                    if !output_set.insert(descriptor.outpoint) { return Err(()); }
                },
                SpendableOutputDescriptor::StaticOutput { ref outpoint, ref output } => {
                    input.push(TxIn {
                        previous_output: outpoint.into_bitcoin_outpoint(),
                        script_sig: Script::new(),
                        sequence: 0,
                        witness: Vec::new(),
                    });
                    witness_weight += 1 + 73 + 34;
                    input_value += output.value;
                    if !output_set.insert(*outpoint) { return Err(()); }
                }
            }
            if input_value > MAX_VALUE_MSAT / 1000 { return Err(()); }
        }
        let mut spend_tx = Transaction {
            version: 2,
            lock_time: 0,
            input,
            output: outputs,
        };
        transaction_utils::maybe_add_change_output(&mut spend_tx, input_value, witness_weight, feerate_sat_per_1000_weight, change_destination_script)?;

        let mut keys_cache: Option<(DynSigner, [u8; 32])> = None;
        let mut input_idx = 0;
        for outp in descriptors {
            match outp {
                SpendableOutputDescriptor::StaticPaymentOutput(descriptor) => {
                    if keys_cache.is_none() || keys_cache.as_ref().unwrap().1 != descriptor.channel_keys_id {
                        keys_cache = Some((
                            self.derive_channel_keys(descriptor.channel_value_satoshis, &descriptor.channel_keys_id),
                            descriptor.channel_keys_id));
                    }
                    spend_tx.input[input_idx].witness = keys_cache.as_ref().unwrap().0.sign_counterparty_payment_input_t(&spend_tx, input_idx, &descriptor, &secp_ctx).unwrap();
                },
                SpendableOutputDescriptor::DelayedPaymentOutput(descriptor) => {
                    if keys_cache.is_none() || keys_cache.as_ref().unwrap().1 != descriptor.channel_keys_id {
                        keys_cache = Some((
                            self.derive_channel_keys(descriptor.channel_value_satoshis, &descriptor.channel_keys_id),
                            descriptor.channel_keys_id));
                    }
                    spend_tx.input[input_idx].witness = keys_cache.as_ref().unwrap().0.sign_dynamic_p2wsh_input_t(&spend_tx, input_idx, &descriptor, &secp_ctx).unwrap();
                },
                SpendableOutputDescriptor::StaticOutput { ref output, .. } => {
                    let derivation_idx = if output.script_pubkey == self.destination_script {
                        1
                    } else {
                        2
                    };
                    let secret = {
                        // Note that when we aren't serializing the key, network doesn't matter
                        match ExtendedPrivKey::new_master(Network::Testnet, &self.seed) {
                            Ok(master_key) => {
                                match master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(derivation_idx).expect("key space exhausted")) {
                                    Ok(key) => key,
                                    Err(_) => panic!("Your RNG is busted"),
                                }
                            }
                            Err(_) => panic!("Your rng is busted"),
                        }
                    };
                    let pubkey = ExtendedPubKey::from_private(&secp_ctx, &secret).public_key;
                    if derivation_idx == 2 {
                        assert_eq!(pubkey.key, self.shutdown_pubkey);
                    }
                    let witness_script = bitcoin::Address::p2pkh(&pubkey, Network::Testnet).script_pubkey();
                    let sighash = ::bitcoin::secp256k1::Message::from_slice(&bip143::SigHashCache::new(&spend_tx).signature_hash(input_idx, &witness_script, output.value, SigHashType::All)[..]).unwrap();
                    let sig = secp_ctx.sign(&sighash, &secret.private_key.key);
                    spend_tx.input[input_idx].witness.push(sig.serialize_der().to_vec());
                    spend_tx.input[input_idx].witness[0].push(SigHashType::All as u8);
                    spend_tx.input[input_idx].witness.push(pubkey.key.serialize().to_vec());
                },
            }
            input_idx += 1;
        }
        Ok(spend_tx)
    }
/// Creates a Transaction which spends the given descriptors to the given outputs, plus an
/// output to the given change destination (if sufficient change value remains). The
/// transaction will have a feerate, at least, of the given value.
///
/// Returns `Err(())` if the output value is greater than the input value minus required fee or
/// if a descriptor was duplicated.
///
/// We do not enforce that outputs meet the dust limit or that any output scripts are standard.
///
/// May panic if the `SpendableOutputDescriptor`s were not generated by Channels which used
/// this KeysManager or one of the `DynSigner` created by this KeysManager.
Creates a Transaction which spends the given descriptors to the given outputs, plus an
output to the given change destination (if sufficient change value remains). The
transaction will have a feerate, at least, of the given value.

Returns `Err(())` if the output value is greater than the input value minus required fee or
if a descriptor was duplicated.

We do not enforce that outputs meet the dust limit or that any output scripts are standard.

May panic if the `SpendableOutputDescriptor`s were not generated by Channels which used
this KeysManager or one of the `DynSigner` created by this KeysManager.
Creates a Transaction which spends the given descriptors to the given outputs plus an output to the given change destination ( if sufficient change value remains ) . The transaction will have a feerate at least of the given value . Returns ` Err (( )) ` if the output value is greater than the input value minus required fee or if a descriptor was duplicated . We do not enforce that outputs meet the dust limit or that any output scripts are standard . May panic if the ` SpendableOutputDescriptor ` s were not generated by Channels which used this KeysManager or one of the ` DynSigner ` created by this KeysManager .
fn spend_spendable_outputs(&self, descriptors: &[&SpendableOutputDescriptor], outputs: Vec<TxOut>, change_destination_script: Script, feerate_sat_per_1000_weight: u32, secp_ctx: &Secp256k1<All>) -> Result<Transaction, ()> {
        let mut input = Vec::new();
        let mut input_value = 0;
        let mut witness_weight = 0;
        let mut output_set = HashSet::with_capacity(descriptors.len());
        for outp in descriptors {
            match outp {
                SpendableOutputDescriptor::StaticPaymentOutput(descriptor) => {
                    input.push(TxIn {
                        previous_output: descriptor.outpoint.into_bitcoin_outpoint(),
                        script_sig: Script::new(),
                        sequence: 0,
                        witness: Vec::new(),
                    });
                    witness_weight += StaticPaymentOutputDescriptor::MAX_WITNESS_LENGTH;
                    input_value += descriptor.output.value;
                    if !output_set.insert(descriptor.outpoint) { return Err(()); }
                },
                SpendableOutputDescriptor::DelayedPaymentOutput(descriptor) => {
                    input.push(TxIn {
                        previous_output: descriptor.outpoint.into_bitcoin_outpoint(),
                        script_sig: Script::new(),
                        sequence: descriptor.to_self_delay as u32,
                        witness: Vec::new(),
                    });
                    witness_weight += DelayedPaymentOutputDescriptor::MAX_WITNESS_LENGTH;
                    input_value += descriptor.output.value;
                    if !output_set.insert(descriptor.outpoint) { return Err(()); }
                },
                SpendableOutputDescriptor::StaticOutput { ref outpoint, ref output } => {
                    input.push(TxIn {
                        previous_output: outpoint.into_bitcoin_outpoint(),
                        script_sig: Script::new(),
                        sequence: 0,
                        witness: Vec::new(),
                    });
                    witness_weight += 1 + 73 + 34;
                    input_value += output.value;
                    if !output_set.insert(*outpoint) { return Err(()); }
                }
            }
            if input_value > MAX_VALUE_MSAT / 1000 { return Err(()); }
        }
        let mut spend_tx = Transaction {
            version: 2,
            lock_time: 0,
            input,
            output: outputs,
        };
        transaction_utils::maybe_add_change_output(&mut spend_tx, input_value, witness_weight, feerate_sat_per_1000_weight, change_destination_script)?;
        let mut keys_cache: Option<(DynSigner, [u8; 32])> = None;
        let mut input_idx = 0;
        for outp in descriptors {
            match outp {
                SpendableOutputDescriptor::StaticPaymentOutput(descriptor) => {
                    if keys_cache.is_none() || keys_cache.as_ref().unwrap().1 != descriptor.channel_keys_id {
                        keys_cache = Some((
                            self.derive_channel_keys(descriptor.channel_value_satoshis, &descriptor.channel_keys_id),
                            descriptor.channel_keys_id));
                    }
                    spend_tx.input[input_idx].witness = keys_cache.as_ref().unwrap().0.sign_counterparty_payment_input_t(&spend_tx, input_idx, &descriptor, &secp_ctx).unwrap();
                },
                SpendableOutputDescriptor::DelayedPaymentOutput(descriptor) => {
                    if keys_cache.is_none() || keys_cache.as_ref().unwrap().1 != descriptor.channel_keys_id {
                        keys_cache = Some((
                            self.derive_channel_keys(descriptor.channel_value_satoshis, &descriptor.channel_keys_id),
                            descriptor.channel_keys_id));
                    }
                    spend_tx.input[input_idx].witness = keys_cache.as_ref().unwrap().0.sign_dynamic_p2wsh_input_t(&spend_tx, input_idx, &descriptor, &secp_ctx).unwrap();
                },
                SpendableOutputDescriptor::StaticOutput { ref output, .. } => {
                    let derivation_idx = if output.script_pubkey == self.destination_script {
                        1
                    } else {
                        2
                    };
                    let secret = {
                        // Note that when we aren't serializing the key, network doesn't matter
                        match ExtendedPrivKey::new_master(Network::Testnet, &self.seed) {
                            Ok(master_key) => {
                                match master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(derivation_idx).expect("key space exhausted")) {
                                    Ok(key) => key,
                                    Err(_) => panic!("Your RNG is busted"),
                                }
                            }
                            Err(_) => panic!("Your rng is busted"),
                        }
                    };
                    let pubkey = ExtendedPubKey::from_private(&secp_ctx, &secret).public_key;
                    if derivation_idx == 2 {
                        assert_eq!(pubkey.key, self.shutdown_pubkey);
                    }
                    let witness_script = bitcoin::Address::p2pkh(&pubkey, Network::Testnet).script_pubkey();
                    let sighash = ::bitcoin::secp256k1::Message::from_slice(&bip143::SigHashCache::new(&spend_tx).signature_hash(input_idx, &witness_script, output.value, SigHashType::All)[..]).unwrap();
                    let sig = secp_ctx.sign(&sighash, &secret.private_key.key);
                    spend_tx.input[input_idx].witness.push(sig.serialize_der().to_vec());
                    spend_tx.input[input_idx].witness[0].push(SigHashType::All as u8);
                    spend_tx.input[input_idx].witness.push(pubkey.key.serialize().to_vec());
                },
            }
            input_idx += 1;
        }
        Ok(spend_tx)
    }
fn spend_spendable_outputs ( & self , descriptors : & [ & SpendableOutputDescriptor ] , outputs : Vec < TxOut > , change_destination_script : Script , feerate_sat_per_1000_weight : u32 , secp_ctx : & Secp256k1 < All > ) -> Result < Transaction , ( ) > { let mut input = Vec :: new ( ) ; let mut input_value = 0 ; let mut witness_weight = 0 ; let mut output_set = HashSet :: with_capacity ( descriptors . len ( ) ) ; for outp in descriptors { match outp { SpendableOutputDescriptor :: StaticPaymentOutput ( descriptor ) => { input . push ( TxIn { previous_output : descriptor . outpoint . into_bitcoin_outpoint ( ) , script_sig : Script :: new ( ) , sequence : 0 , witness : Vec :: new ( ) , } ) ; witness_weight += StaticPaymentOutputDescriptor :: MAX_WITNESS_LENGTH ; input_value += descriptor . output . value ; if ! output_set . insert ( descriptor . outpoint ) { return Err ( ( ) ) ; } } , SpendableOutputDescriptor :: DelayedPaymentOutput ( descriptor ) => { input . push ( TxIn { previous_output : descriptor . outpoint . into_bitcoin_outpoint ( ) , script_sig : Script :: new ( ) , sequence : descriptor . to_self_delay as u32 , witness : Vec :: new ( ) , } ) ; witness_weight += DelayedPaymentOutputDescriptor :: MAX_WITNESS_LENGTH ; input_value += descriptor . output . value ; if ! output_set . insert ( descriptor . outpoint ) { return Err ( ( ) ) ; } } , SpendableOutputDescriptor :: StaticOutput { ref outpoint , ref output } => { input . push ( TxIn { previous_output : outpoint . into_bitcoin_outpoint ( ) , script_sig : Script :: new ( ) , sequence : 0 , witness : Vec :: new ( ) , } ) ; witness_weight += 1 + 73 + 34 ; input_value += output . value ; if ! output_set . insert ( * outpoint ) { return Err ( ( ) ) ; } } } if input_value > MAX_VALUE_MSAT / 1000 { return Err ( ( ) ) ; } } let mut spend_tx = Transaction { version : 2 , lock_time : 0 , input , output : outputs , } ; transaction_utils :: maybe_add_change_output ( & mut spend_tx , input_value , witness_weight , feerate_sat_per_1000_weight , change_destination_script ) ? ; let mut keys_cache : Option < ( DynSigner , [ u8 ; 32 ] ) > = None ; let mut input_idx = 0 ; for outp in descriptors { match outp { SpendableOutputDescriptor :: StaticPaymentOutput ( descriptor ) => { if keys_cache . is_none ( ) || keys_cache . as_ref ( ) . unwrap ( ) . 1 != descriptor . channel_keys_id { keys_cache = Some ( ( self . derive_channel_keys ( descriptor . channel_value_satoshis , & descriptor . channel_keys_id ) , descriptor . channel_keys_id ) ) ; } spend_tx . input [ input_idx ] . witness = keys_cache . as_ref ( ) . unwrap ( ) . 0 . sign_counterparty_payment_input_t ( & spend_tx , input_idx , & descriptor , & secp_ctx ) . unwrap ( ) ; } , SpendableOutputDescriptor :: DelayedPaymentOutput ( descriptor ) => { if keys_cache . is_none ( ) || keys_cache . as_ref ( ) . unwrap ( ) . 1 != descriptor . channel_keys_id { keys_cache = Some ( ( self . derive_channel_keys ( descriptor . channel_value_satoshis , & descriptor . channel_keys_id ) , descriptor . channel_keys_id ) ) ; } spend_tx . input [ input_idx ] . witness = keys_cache . as_ref ( ) . unwrap ( ) . 0 . sign_dynamic_p2wsh_input_t ( & spend_tx , input_idx , & descriptor , & secp_ctx ) . unwrap ( ) ; } , SpendableOutputDescriptor :: StaticOutput { ref output , .. } => { let derivation_idx = if output . script_pubkey == self . destination_script { 1 } else { 2 } ; let secret = { // Note that when we aren't serializing the key, network doesn't matter match ExtendedPrivKey :: new_master ( Network :: Testnet , & self . seed ) { Ok ( master_key ) => { match master_key . ckd_priv ( & secp_ctx , ChildNumber :: from_hardened_idx ( derivation_idx ) . expect ( " " ) ) { Ok ( key ) => key , Err ( _ ) => panic ! ( " " ) , } } Err ( _ ) => panic ! ( " " ) , } } ; let pubkey = ExtendedPubKey :: from_private ( & secp_ctx , & secret ) . public_key ; if derivation_idx == 2 { assert_eq ! ( pubkey key self shutdown_pubkey ) ; } let witness_script = bitcoin :: Address :: p2pkh ( & pubkey , Network :: Testnet ) . script_pubkey ( ) ; let sighash = :: bitcoin :: secp256k1 :: Message :: from_slice ( & bip143 :: SigHashCache :: new ( & spend_tx ) . signature_hash ( input_idx , & witness_script , output . value , SigHashType :: All ) [ .. ] ) . unwrap ( ) ; let sig = secp_ctx . sign ( & sighash , & secret . private_key . key ) ; spend_tx . input [ input_idx ] . witness . push ( sig . serialize_der ( ) . to_vec ( ) ) ; spend_tx . input [ input_idx ] . witness [ 0 ] . push ( SigHashType :: All as u8 ) ; spend_tx . input [ input_idx ] . witness . push ( pubkey . key . serialize ( ) . to_vec ( ) ) ; } , } input_idx += 1 ; } Ok ( spend_tx ) }
Creates a Transaction which spends the given descriptors to the given outputs, plus an
output to the given change destination (if sufficient change value remains).
Creates a Transaction which spends the given descriptors to the given outputs plus an output to the given change destination ( if sufficient change value remains ) .
&self
descriptors
&[&SpendableOutputDescriptor]
outputs
Vec<TxOut>
change_destination_script
Script
feerate_sat_per_1000_weight
u32
secp_ctx
&Secp256k1<All>
&self
descriptors
&[&SpendableOutputDescriptor]
outputs
Vec<TxOut>
change_destination_script
Script
feerate_sat_per_1000_weight
u32
secp_ctx
&Secp256k1<All>