X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchan_utils.rs;h=ba175733abeb632065d0cf16fe44ca13b6560b66;hb=b19d4475cbfb4c784d7f2ba3125baf31c81d4df0;hp=949d008c0d7d23ff69af82e8c80f568814875233;hpb=0d77e7ce86aa22d147be1925c2e62742ca967f80;p=rust-lightning diff --git a/lightning/src/ln/chan_utils.rs b/lightning/src/ln/chan_utils.rs index 949d008c..ba175733 100644 --- a/lightning/src/ln/chan_utils.rs +++ b/lightning/src/ln/chan_utils.rs @@ -52,7 +52,8 @@ impl HTLCType { // Various functions for key derivation and transaction creation for use within channels. Primarily // used in Channel and ChannelMonitor. -pub(super) fn build_commitment_secret(commitment_seed: &[u8; 32], idx: u64) -> [u8; 32] { +/// Build the commitment secret from the seed and the commitment number +pub fn build_commitment_secret(commitment_seed: &[u8; 32], idx: u64) -> [u8; 32] { let mut res: [u8; 32] = commitment_seed.clone(); for i in 0..48 { let bitpos = 47 - i; @@ -172,8 +173,11 @@ impl Readable for CounterpartyCommitmentSecrets { } } -/// Derives a per-commitment-transaction private key (eg an htlc key or payment key) from the base -/// private key for that type of key and the per_commitment_point (available in TxCreationKeys) +/// Derives a per-commitment-transaction private key (eg an htlc key or delayed_payment key) +/// from the base secret and the per_commitment_point. +/// +/// Note that this is infallible iff we trust that at least one of the two input keys are randomly +/// generated (ie our own). pub fn derive_private_key(secp_ctx: &Secp256k1, per_commitment_point: &PublicKey, base_secret: &SecretKey) -> Result { let mut sha = Sha256::engine(); sha.input(&per_commitment_point.serialize()); @@ -185,7 +189,13 @@ pub fn derive_private_key(secp_ctx: &Secp256k1, per_co Ok(key) } -pub(super) fn derive_public_key(secp_ctx: &Secp256k1, per_commitment_point: &PublicKey, base_point: &PublicKey) -> Result { +/// Derives a per-commitment-transaction public key (eg an htlc key or a delayed_payment key) +/// from the base point and the per_commitment_key. This is the public equivalent of +/// derive_private_key - using only public keys to derive a public key instead of private keys. +/// +/// Note that this is infallible iff we trust that at least one of the two input keys are randomly +/// generated (ie our own). +pub fn derive_public_key(secp_ctx: &Secp256k1, per_commitment_point: &PublicKey, base_point: &PublicKey) -> Result { let mut sha = Sha256::engine(); sha.input(&per_commitment_point.serialize()); sha.input(&base_point.serialize()); @@ -195,10 +205,11 @@ pub(super) fn derive_public_key(secp_ctx: &Secp256k1, base_point.combine(&hashkey) } -/// Derives a revocation key from its constituent parts. +/// Derives a per-commitment-transaction revocation key from its constituent parts. +/// /// Note that this is infallible iff we trust that at least one of the two input keys are randomly /// generated (ie our own). -pub(super) fn derive_private_revocation_key(secp_ctx: &Secp256k1, per_commitment_secret: &SecretKey, revocation_base_secret: &SecretKey) -> Result { +pub fn derive_private_revocation_key(secp_ctx: &Secp256k1, per_commitment_secret: &SecretKey, revocation_base_secret: &SecretKey) -> Result { let revocation_base_point = PublicKey::from_secret_key(&secp_ctx, &revocation_base_secret); let per_commitment_point = PublicKey::from_secret_key(&secp_ctx, &per_commitment_secret); @@ -225,7 +236,13 @@ pub(super) fn derive_private_revocation_key(secp_ctx: &Se Ok(part_a) } -pub(super) fn derive_public_revocation_key(secp_ctx: &Secp256k1, per_commitment_point: &PublicKey, revocation_base_point: &PublicKey) -> Result { +/// Derives a per-commitment-transaction revocation public key from its constituent parts. This is +/// the public equivalend of derive_private_revocation_key - using only public keys to derive a +/// public key instead of private keys. +/// +/// Note that this is infallible iff we trust that at least one of the two input keys are randomly +/// generated (ie our own). +pub fn derive_public_revocation_key(secp_ctx: &Secp256k1, per_commitment_point: &PublicKey, revocation_base_point: &PublicKey) -> Result { let rev_append_commit_hash_key = { let mut sha = Sha256::engine(); sha.input(&revocation_base_point.serialize()); @@ -274,9 +291,9 @@ pub struct ChannelPublicKeys { /// on-chain channel lock-in 2-of-2 multisig output. pub funding_pubkey: PublicKey, /// The base point which is used (with derive_public_revocation_key) to derive per-commitment - /// revocation keys. The per-commitment revocation private key is then revealed by the owner of - /// a commitment transaction so that their counterparty can claim all available funds if they - /// broadcast an old state. + /// revocation keys. This is combined with the per-commitment-secret generated by the + /// counterparty to create a secret which the counterparty can reveal to revoke previous + /// states. pub revocation_basepoint: PublicKey, /// The public key which receives our immediately spendable primary channel balance in /// remote-broadcasted commitment transactions. This key is static across every commitment @@ -312,9 +329,10 @@ impl TxCreationKeys { } } -/// Gets the "to_local" output redeemscript, ie the script which is time-locked or spendable by -/// the revocation key -pub(super) fn get_revokeable_redeemscript(revocation_key: &PublicKey, to_self_delay: u16, delayed_payment_key: &PublicKey) -> Script { +/// A script either spendable by the revocation +/// key or the delayed_payment_key and satisfying the relative-locktime OP_CSV constrain. +/// Encumbering a `to_local` output on a commitment transaction or 2nd-stage HTLC transactions. +pub fn get_revokeable_redeemscript(revocation_key: &PublicKey, to_self_delay: u16, delayed_payment_key: &PublicKey) -> Script { Builder::new().push_opcode(opcodes::all::OP_IF) .push_slice(&revocation_key.serialize()) .push_opcode(opcodes::all::OP_ELSE) @@ -445,7 +463,7 @@ pub fn make_funding_redeemscript(a: &PublicKey, b: &PublicKey) -> Script { } /// panics if htlc.transaction_output_index.is_none()! -pub fn build_htlc_transaction(prev_hash: &Txid, feerate_per_kw: u64, to_self_delay: u16, htlc: &HTLCOutputInCommitment, a_delayed_payment_key: &PublicKey, revocation_key: &PublicKey) -> Transaction { +pub fn build_htlc_transaction(prev_hash: &Txid, feerate_per_kw: u32, to_self_delay: u16, htlc: &HTLCOutputInCommitment, a_delayed_payment_key: &PublicKey, revocation_key: &PublicKey) -> Transaction { let mut txins: Vec = Vec::new(); txins.push(TxIn { previous_output: OutPoint { @@ -458,9 +476,9 @@ pub fn build_htlc_transaction(prev_hash: &Txid, feerate_per_kw: u64, to_self_del }); let total_fee = if htlc.offered { - feerate_per_kw * HTLC_TIMEOUT_TX_WEIGHT / 1000 + feerate_per_kw as u64 * HTLC_TIMEOUT_TX_WEIGHT / 1000 } else { - feerate_per_kw * HTLC_SUCCESS_TX_WEIGHT / 1000 + feerate_per_kw as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000 }; let mut txouts: Vec = Vec::new(); @@ -479,8 +497,8 @@ pub fn build_htlc_transaction(prev_hash: &Txid, feerate_per_kw: u64, to_self_del #[derive(Clone)] /// We use this to track local commitment transactions and put off signing them until we are ready -/// to broadcast. Eventually this will require a signer which is possibly external, but for now we -/// just pass in the SecretKeys required. +/// to broadcast. This class can be used inside a signer implementation to generate a signature +/// given the relevant secret key. pub struct LocalCommitmentTransaction { // TODO: We should migrate away from providing the transaction, instead providing enough to // allow the ChannelKeys to construct it from scratch. Luckily we already have HTLC data here, @@ -496,7 +514,7 @@ pub struct LocalCommitmentTransaction { pub local_keys: TxCreationKeys, /// The feerate paid per 1000-weight-unit in this commitment transaction. This value is /// controlled by the channel initiator. - pub feerate_per_kw: u64, + pub feerate_per_kw: u32, /// The HTLCs and remote htlc signatures which were included in this commitment transaction. /// /// Note that this includes all HTLCs, including ones which were considered dust and not @@ -544,7 +562,7 @@ impl LocalCommitmentTransaction { /// Generate a new LocalCommitmentTransaction based on a raw commitment transaction, /// remote signature and both parties keys - pub(crate) fn new_missing_local_sig(unsigned_tx: Transaction, their_sig: Signature, our_funding_key: &PublicKey, their_funding_key: &PublicKey, local_keys: TxCreationKeys, feerate_per_kw: u64, htlc_data: Vec<(HTLCOutputInCommitment, Option)>) -> LocalCommitmentTransaction { + pub(crate) fn new_missing_local_sig(unsigned_tx: Transaction, their_sig: Signature, our_funding_key: &PublicKey, their_funding_key: &PublicKey, local_keys: TxCreationKeys, feerate_per_kw: u32, htlc_data: Vec<(HTLCOutputInCommitment, Option)>) -> LocalCommitmentTransaction { if unsigned_tx.input.len() != 1 { panic!("Tried to store a commitment transaction that had input count != 1!"); } if unsigned_tx.input[0].witness.len() != 0 { panic!("Tried to store a signed commitment transaction?"); }