Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 480
Move spendable output descriptors key behind signer interface#562
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
3244e413caa38fea8df9db082827bb5b14cd2a6a785a8f68f4fd727f13a66047a23c0cFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -2,11 +2,12 @@ | ||
| //! spendable on-chain outputs which the user owns and is responsible for using just as any other | ||
| //! on-chain output which is theirs. | ||
| use bitcoin::blockdata::transaction::{Transaction, OutPoint, TxOut}; | ||
| use bitcoin::blockdata::transaction::{Transaction, OutPoint, TxOut, SigHashType}; | ||
| use bitcoin::blockdata::script::{Script, Builder}; | ||
| use bitcoin::blockdata::opcodes; | ||
| use bitcoin::network::constants::Network; | ||
| use bitcoin::util::bip32::{ExtendedPrivKey, ExtendedPubKey, ChildNumber}; | ||
| use bitcoin::util::address::Address; | ||
| use bitcoin::util::bip143; | ||
| use bitcoin_hashes::{Hash, HashEngine}; | ||
| @@ -26,6 +27,7 @@ use util::ser::{Writeable, Writer, Readable}; | ||
| use ln::chan_utils; | ||
| use ln::chan_utils::{TxCreationKeys, HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, LocalCommitmentTransaction}; | ||
| use ln::msgs; | ||
| use ln::channelmanager::PaymentPreimage; | ||
| use std::sync::Arc; | ||
| use std::sync::atomic::{AtomicUsize, Ordering}; | ||
| @@ -64,8 +66,8 @@ pub enum SpendableOutputDescriptor { | ||
| DynamicOutputP2WSH { | ||
| /// The outpoint which is spendable | ||
| outpoint: OutPoint, | ||
| /// The secret key which must be used to sign the spending transaction | ||
| key: SecretKey, | ||
| /// Per commitment point to derive delayed_payment_key by key holder | ||
| per_commitment_point: PublicKey, | ||
| /// The witness redeemScript which is hashed to create the script_pubkey in the given output | ||
| witness_script: Script, | ||
| /// The nSequence value which must be set in the spending input to satisfy the OP_CSV in | ||
| @@ -83,7 +85,7 @@ pub enum SpendableOutputDescriptor { | ||
| /// The outpoint which is spendable | ||
| outpoint: OutPoint, | ||
| /// The secret key which must be used to sign the spending transaction | ||
| key: SecretKey, | ||
| per_commitment_point: PublicKey, | ||
| /// The output which is reference by the given outpoint | ||
| output: TxOut, | ||
| } | ||
| @@ -97,18 +99,18 @@ impl Writeable for SpendableOutputDescriptor { | ||
| outpoint.write(writer)?; | ||
| output.write(writer)?; | ||
| }, | ||
| &SpendableOutputDescriptor::DynamicOutputP2WSH { ref outpoint, ref key, ref witness_script, ref to_self_delay, ref output } => { | ||
| &SpendableOutputDescriptor::DynamicOutputP2WSH { ref outpoint, ref per_commitment_point, ref witness_script, ref to_self_delay, ref output } => { | ||
| 1u8.write(writer)?; | ||
| outpoint.write(writer)?; | ||
| key.write(writer)?; | ||
| per_commitment_point.write(writer)?; | ||
| witness_script.write(writer)?; | ||
| to_self_delay.write(writer)?; | ||
| output.write(writer)?; | ||
| }, | ||
| &SpendableOutputDescriptor::DynamicOutputP2WPKH { ref outpoint, ref key, ref output } => { | ||
| &SpendableOutputDescriptor::DynamicOutputP2WPKH { ref outpoint, ref per_commitment_point, ref output } => { | ||
| 2u8.write(writer)?; | ||
| outpoint.write(writer)?; | ||
| key.write(writer)?; | ||
| per_commitment_point.write(writer)?; | ||
| output.write(writer)?; | ||
| }, | ||
| } | ||
| @@ -125,14 +127,14 @@ impl Readable for SpendableOutputDescriptor { | ||
| }), | ||
| 1u8 => Ok(SpendableOutputDescriptor::DynamicOutputP2WSH { | ||
| outpoint: Readable::read(reader)?, | ||
| key: Readable::read(reader)?, | ||
| per_commitment_point: Readable::read(reader)?, | ||
| witness_script: Readable::read(reader)?, | ||
| to_self_delay: Readable::read(reader)?, | ||
| output: Readable::read(reader)?, | ||
| }), | ||
| 2u8 => Ok(SpendableOutputDescriptor::DynamicOutputP2WPKH { | ||
| outpoint: Readable::read(reader)?, | ||
| key: Readable::read(reader)?, | ||
| per_commitment_point: Readable::read(reader)?, | ||
| output: Readable::read(reader)?, | ||
| }), | ||
| _ => Err(DecodeError::InvalidValue), | ||
| @@ -245,12 +247,24 @@ pub trait ChannelKeys : Send+Clone { | ||
| /// return value must contain a signature. | ||
| fn sign_local_commitment_htlc_transactions<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, local_csv: u16, secp_ctx: &Secp256k1<T>) -> Result<Vec<Option<Signature>>, ()>; | ||
| /// Signs a justice transaction. | ||
| fn sign_justice_transaction<T: secp256k1::Signing>(&self, bumped_tx: &mut Transaction, input: usize, witness_script: &Script, amount: u64, per_commitment_key: &SecretKey, revocation_pubkey: &PublicKey, is_htlc: bool, secp_ctx: &Secp256k1<T>); | ||
| /// Signs a remote htlc transaction. | ||
| fn sign_remote_htlc_transaction<T: secp256k1::Signing>(&self, bumped_tx: &mut Transaction, input: usize, witness_script: &Script, amount: u64, per_commitment_point: &PublicKey, preimage: &Option<PaymentPreimage>, secp_ctx: &Secp256k1<T>); | ||
| /// Create a signature for a (proposed) closing transaction. | ||
| /// | ||
| /// Note that, due to rounding, there may be one "missing" satoshi, and either party may have | ||
| /// chosen to forgo their output as dust. | ||
| fn sign_closing_transaction<T: secp256k1::Signing>(&self, closing_tx: &Transaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()>; | ||
| /// Create a signature for a delayed transaction. | ||
| fn sign_delayed_transaction<T: secp256k1::Signing>(&self, spend_tx: &mut Transaction, input: usize, witness_script: &Script, amount: u64, per_commitment_point: &PublicKey, secp_ctx: &Secp256k1<T>); | ||
| /// Create a signture for a payment transaction spending a to_remote output on a remote commitment tx. | ||
| fn sign_payment_transaction<T: secp256k1::Signing>(&self, spend_tx: &mut Transaction, input: usize, amount: u64, per_commitment_point: &PublicKey, network: Network, secp_ctx: &Secp256k1<T>); | ||
| /// Signs a channel announcement message with our funding key, proving it comes from one | ||
| /// of the channel participants. | ||
| /// | ||
| @@ -393,6 +407,38 @@ impl ChannelKeys for InMemoryChannelKeys { | ||
| local_commitment_tx.get_htlc_sigs(&self.htlc_base_key, local_csv, secp_ctx) | ||
| } | ||
| fn sign_justice_transaction<T: secp256k1::Signing>(&self, bumped_tx: &mut Transaction, input: usize, witness_script: &Script, amount: u64, per_commitment_key: &SecretKey, revocation_pubkey: &PublicKey, is_htlc: bool, secp_ctx: &Secp256k1<T>) { | ||
| if let Ok(revocation_key) = chan_utils::derive_private_revocation_key(&secp_ctx, &per_commitment_key, &self.revocation_base_key) { | ||
| let sighash_parts = bip143::SighashComponents::new(&bumped_tx); | ||
| let sighash = hash_to_message!(&sighash_parts.sighash_all(&bumped_tx.input[input], &witness_script, amount)[..]); | ||
| let sig = secp_ctx.sign(&sighash, &revocation_key); | ||
| bumped_tx.input[input].witness.push(sig.serialize_der().to_vec()); | ||
| bumped_tx.input[input].witness[0].push(SigHashType::All as u8); | ||
| if is_htlc { | ||
| bumped_tx.input[input].witness.push(revocation_pubkey.clone().serialize().to_vec()); | ||
| } else { | ||
| bumped_tx.input[input].witness.push(vec!(1)); | ||
| } | ||
| bumped_tx.input[input].witness.push(witness_script.clone().into_bytes()); | ||
| } | ||
| } | ||
| fn sign_remote_htlc_transaction<T: secp256k1::Signing>(&self, bumped_tx: &mut Transaction, input: usize, witness_script: &Script, amount: u64, per_commitment_point: &PublicKey, preimage: &Option<PaymentPreimage>, secp_ctx: &Secp256k1<T>) { | ||
| if let Ok(htlc_key) = chan_utils::derive_private_key(&secp_ctx, &per_commitment_point, &self.htlc_base_key) { | ||
| let sighash_parts = bip143::SighashComponents::new(&bumped_tx); | ||
| let sighash = hash_to_message!(&sighash_parts.sighash_all(&bumped_tx.input[input], &witness_script, amount)[..]); | ||
| let sig = secp_ctx.sign(&sighash, &htlc_key); | ||
| bumped_tx.input[input].witness.push(sig.serialize_der().to_vec()); | ||
| bumped_tx.input[input].witness[0].push(SigHashType::All as u8); | ||
| if let &Some(preimage) = preimage { | ||
| bumped_tx.input[input].witness.push(preimage.0.to_vec()); | ||
| } else { | ||
| bumped_tx.input[input].witness.push(vec![0]); | ||
| } | ||
| bumped_tx.input[input].witness.push(witness_script.clone().into_bytes()); | ||
| } | ||
| } | ||
| fn sign_closing_transaction<T: secp256k1::Signing>(&self, closing_tx: &Transaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> { | ||
| if closing_tx.input.len() != 1 { return Err(()); } | ||
| if closing_tx.input[0].witness.len() != 0 { return Err(()); } | ||
| @@ -407,6 +453,31 @@ impl ChannelKeys for InMemoryChannelKeys { | ||
| Ok(secp_ctx.sign(&sighash, &self.funding_key)) | ||
| } | ||
| fn sign_delayed_transaction<T: secp256k1::Signing>(&self, spend_tx: &mut Transaction, input: usize, witness_script: &Script, amount: u64, per_commitment_point: &PublicKey, secp_ctx: &Secp256k1<T>) { | ||
| if let Ok(htlc_key) = chan_utils::derive_private_key(&secp_ctx, &per_commitment_point, &self.delayed_payment_base_key) { | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. failing here likely indicates a serious internal error, so should propagate the error to the caller | ||
| let sighash_parts = bip143::SighashComponents::new(&spend_tx); | ||
| let sighash = hash_to_message!(&sighash_parts.sighash_all(&spend_tx.input[input], witness_script, amount)[..]); | ||
| let local_delaysig = secp_ctx.sign(&sighash, &htlc_key); | ||
| spend_tx.input[0].witness.push(local_delaysig.serialize_der().to_vec()); | ||
| spend_tx.input[0].witness[0].push(SigHashType::All as u8); | ||
| spend_tx.input[0].witness.push(vec!(0)); | ||
| spend_tx.input[0].witness.push(witness_script.clone().into_bytes()); | ||
| } | ||
| } | ||
| fn sign_payment_transaction<T: secp256k1::Signing>(&self, spend_tx: &mut Transaction, input: usize, amount: u64, per_commitment_point: &PublicKey, network: Network, secp_ctx: &Secp256k1<T>) { | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. see two comments on | ||
| if let Ok(payment_key) = chan_utils::derive_private_key(&secp_ctx, &per_commitment_point, &self.payment_base_key) { | ||
| let remotepubkey = PublicKey::from_secret_key(&secp_ctx, &payment_key); | ||
| let witness_script = Address::p2pkh(&::bitcoin::PublicKey{compressed: true, key: remotepubkey}, network).script_pubkey(); | ||
| let sighash_parts = bip143::SighashComponents::new(&spend_tx); | ||
| let sighash = hash_to_message!(&sighash_parts.sighash_all(&spend_tx.input[input], &witness_script, amount)[..]); | ||
| let remotesig = secp_ctx.sign(&sighash, &payment_key); | ||
| spend_tx.input[0].witness.push(remotesig.serialize_der().to_vec()); | ||
| spend_tx.input[0].witness[0].push(SigHashType::All as u8); | ||
| spend_tx.input[0].witness.push(remotepubkey.serialize().to_vec()); | ||
| } | ||
| } | ||
| fn sign_channel_announcement<T: secp256k1::Signing>(&self, msg: &msgs::UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> { | ||
| let msghash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]); | ||
| Ok(secp_ctx.sign(&msghash, &self.funding_key)) | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the
witness_scriptcould be derived here rather than passed in, if I'm not mistaken