From e885d0a7747cfc3b89a3c2765a8c0dd174e3889a Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 6 Feb 2021 13:11:23 -0500 Subject: [PATCH 1/5] Swap key_derivation_params (u64, u64) for channel_keys_id [u8; 32] Instead of `key_derivation_params` being a rather strange type, we call it `channel_keys_id` and give it a generic 32 byte array. This should be much clearer for users and also more flexible. --- fuzz/src/chanmon_consistency.rs | 2 +- fuzz/src/full_stack.rs | 4 +- lightning/src/chain/channelmonitor.rs | 20 +++---- lightning/src/chain/keysinterface.rs | 62 ++++++++++----------- lightning/src/ln/channel.rs | 2 +- lightning/src/ln/functional_tests.rs | 8 +-- lightning/src/util/enforcing_trait_impls.rs | 2 +- lightning/src/util/test_utils.rs | 4 +- 8 files changed, 52 insertions(+), 52 deletions(-) diff --git a/fuzz/src/chanmon_consistency.rs b/fuzz/src/chanmon_consistency.rs index 8e79ac5f9..4cf90b1dc 100644 --- a/fuzz/src/chanmon_consistency.rs +++ b/fuzz/src/chanmon_consistency.rs @@ -179,7 +179,7 @@ impl KeysInterface for KeyProvider { SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, self.node_id]).unwrap(), [id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, self.node_id], channel_value_satoshis, - (0, 0), + [0; 32], ); let revoked_commitment = self.make_revoked_commitment_cell(keys.commitment_seed); EnforcingChannelKeys::new_with_revoked(keys, revoked_commitment, false) diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index 901c9ef1e..a1e1b7599 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -279,7 +279,7 @@ impl KeysInterface for KeyProvider { SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, ctr]).unwrap(), [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, ctr], channel_value_satoshis, - (0, 0), + [0; 32] ) } else { InMemoryChannelKeys::new( @@ -291,7 +291,7 @@ impl KeysInterface for KeyProvider { SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, ctr]).unwrap(), [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, ctr], channel_value_satoshis, - (0, 0), + [0; 32] ) }) } diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index 95495d1bf..a8258f564 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -632,7 +632,7 @@ pub struct ChannelMonitor { counterparty_payment_script: Script, shutdown_script: Script, - key_derivation_params: (u64, u64), + channel_keys_id: [u8; 32], holder_revocation_basepoint: PublicKey, funding_info: (OutPoint, Script), current_counterparty_commitment_txid: Option, @@ -728,7 +728,7 @@ impl PartialEq for ChannelMonitor { self.destination_script != other.destination_script || self.broadcasted_holder_revokable_script != other.broadcasted_holder_revokable_script || self.counterparty_payment_script != other.counterparty_payment_script || - self.key_derivation_params != other.key_derivation_params || + self.channel_keys_id != other.channel_keys_id || self.holder_revocation_basepoint != other.holder_revocation_basepoint || self.funding_info != other.funding_info || self.current_counterparty_commitment_txid != other.current_counterparty_commitment_txid || @@ -786,7 +786,7 @@ impl Writeable for ChannelMonitor { self.counterparty_payment_script.write(writer)?; self.shutdown_script.write(writer)?; - self.key_derivation_params.write(writer)?; + self.channel_keys_id.write(writer)?; self.holder_revocation_basepoint.write(writer)?; writer.write_all(&self.funding_info.0.txid[..])?; writer.write_all(&byte_utils::be16_to_array(self.funding_info.0.index))?; @@ -967,7 +967,7 @@ impl ChannelMonitor { let counterparty_htlc_base_key = counterparty_channel_parameters.pubkeys.htlc_basepoint; let counterparty_tx_cache = CounterpartyCommitmentTransaction { counterparty_delayed_payment_base_key, counterparty_htlc_base_key, on_counterparty_tx_csv, per_htlc: HashMap::new() }; - let key_derivation_params = keys.key_derivation_params(); + let channel_keys_id = keys.channel_keys_id(); let holder_revocation_basepoint = keys.pubkeys().revocation_basepoint; let secp_ctx = Secp256k1::new(); @@ -1006,7 +1006,7 @@ impl ChannelMonitor { counterparty_payment_script, shutdown_script, - key_derivation_params, + channel_keys_id, holder_revocation_basepoint, funding_info, current_counterparty_commitment_txid: None, @@ -2206,7 +2206,7 @@ impl ChannelMonitor { per_commitment_point: broadcasted_holder_revokable_script.1, to_self_delay: self.on_holder_tx_csv, output: outp.clone(), - key_derivation_params: self.key_derivation_params, + channel_keys_id: self.channel_keys_id, revocation_pubkey: broadcasted_holder_revokable_script.2.clone(), }); break; @@ -2215,7 +2215,7 @@ impl ChannelMonitor { spendable_output = Some(SpendableOutputDescriptor::StaticOutputCounterpartyPayment { outpoint: OutPoint { txid: tx.txid(), index: i as u16 }, output: outp.clone(), - key_derivation_params: self.key_derivation_params, + channel_keys_id: self.channel_keys_id, }); break; } else if outp.script_pubkey == self.shutdown_script { @@ -2332,7 +2332,7 @@ impl<'a, ChanSigner: ChannelKeys, K: KeysInterface> let counterparty_payment_script = Readable::read(reader)?; let shutdown_script = Readable::read(reader)?; - let key_derivation_params = Readable::read(reader)?; + let channel_keys_id = Readable::read(reader)?; let holder_revocation_basepoint = Readable::read(reader)?; // Technically this can fail and serialize fail a round-trip, but only for serialization of // barely-init'd ChannelMonitors that we can't do anything with. @@ -2547,7 +2547,7 @@ impl<'a, ChanSigner: ChannelKeys, K: KeysInterface> counterparty_payment_script, shutdown_script, - key_derivation_params, + channel_keys_id, holder_revocation_basepoint, funding_info, current_counterparty_commitment_txid, @@ -2675,7 +2675,7 @@ mod tests { SecretKey::from_slice(&[41; 32]).unwrap(), [41; 32], 0, - (0, 0) + [0; 32] ); let counterparty_pubkeys = ChannelPublicKeys { diff --git a/lightning/src/chain/keysinterface.rs b/lightning/src/chain/keysinterface.rs index e56ac96f0..f713d70ca 100644 --- a/lightning/src/chain/keysinterface.rs +++ b/lightning/src/chain/keysinterface.rs @@ -100,7 +100,7 @@ pub enum SpendableOutputDescriptor { output: TxOut, /// The channel keys state used to proceed to derivation of signing key. Must /// be pass to KeysInterface::derive_channel_keys. - key_derivation_params: (u64, u64), + channel_keys_id: [u8; 32], /// The revocation_pubkey used to derive witnessScript revocation_pubkey: PublicKey }, @@ -118,7 +118,7 @@ pub enum SpendableOutputDescriptor { output: TxOut, /// The channel keys state used to proceed to derivation of signing key. Must /// be pass to KeysInterface::derive_channel_keys. - key_derivation_params: (u64, u64), + channel_keys_id: [u8; 32], } } @@ -130,22 +130,20 @@ impl Writeable for SpendableOutputDescriptor { outpoint.write(writer)?; output.write(writer)?; }, - &SpendableOutputDescriptor::DynamicOutputP2WSH { ref outpoint, ref per_commitment_point, ref to_self_delay, ref output, ref key_derivation_params, ref revocation_pubkey } => { + &SpendableOutputDescriptor::DynamicOutputP2WSH { ref outpoint, ref per_commitment_point, ref to_self_delay, ref output, ref channel_keys_id, ref revocation_pubkey } => { 1u8.write(writer)?; outpoint.write(writer)?; per_commitment_point.write(writer)?; to_self_delay.write(writer)?; output.write(writer)?; - key_derivation_params.0.write(writer)?; - key_derivation_params.1.write(writer)?; + channel_keys_id.write(writer)?; revocation_pubkey.write(writer)?; }, - &SpendableOutputDescriptor::StaticOutputCounterpartyPayment { ref outpoint, ref output, ref key_derivation_params } => { + &SpendableOutputDescriptor::StaticOutputCounterpartyPayment { ref outpoint, ref output, ref channel_keys_id } => { 2u8.write(writer)?; outpoint.write(writer)?; output.write(writer)?; - key_derivation_params.0.write(writer)?; - key_derivation_params.1.write(writer)?; + channel_keys_id.write(writer)?; }, } Ok(()) @@ -164,13 +162,13 @@ impl Readable for SpendableOutputDescriptor { per_commitment_point: Readable::read(reader)?, to_self_delay: Readable::read(reader)?, output: Readable::read(reader)?, - key_derivation_params: (Readable::read(reader)?, Readable::read(reader)?), + channel_keys_id: Readable::read(reader)?, revocation_pubkey: Readable::read(reader)?, }), 2u8 => Ok(SpendableOutputDescriptor::StaticOutputCounterpartyPayment { outpoint: Readable::read(reader)?, output: Readable::read(reader)?, - key_derivation_params: (Readable::read(reader)?, Readable::read(reader)?), + channel_keys_id: Readable::read(reader)?, }), _ => Err(DecodeError::InvalidValue), } @@ -221,10 +219,10 @@ pub trait ChannelKeys : Send+Clone + Writeable { fn release_commitment_secret(&self, idx: u64) -> [u8; 32]; /// Gets the holder's channel public keys and basepoints fn pubkeys(&self) -> &ChannelPublicKeys; - /// Gets arbitrary identifiers describing the set of keys which are provided back to you in - /// some SpendableOutputDescriptor types. These should be sufficient to identify this + /// Gets an arbitrary identifier describing the set of keys which are provided back to you in + /// some SpendableOutputDescriptor types. This should be sufficient to identify this /// ChannelKeys object uniquely and lookup or re-derive its keys. - fn key_derivation_params(&self) -> (u64, u64); + fn channel_keys_id(&self) -> [u8; 32]; /// Create a signature for a counterparty's commitment transaction and associated HTLC transactions. /// @@ -375,7 +373,7 @@ pub struct InMemoryChannelKeys { /// The total value of this channel channel_value_satoshis: u64, /// Key derivation parameters - key_derivation_params: (u64, u64), + channel_keys_id: [u8; 32], } impl InMemoryChannelKeys { @@ -389,7 +387,7 @@ impl InMemoryChannelKeys { htlc_base_key: SecretKey, commitment_seed: [u8; 32], channel_value_satoshis: u64, - key_derivation_params: (u64, u64)) -> InMemoryChannelKeys { + channel_keys_id: [u8; 32]) -> InMemoryChannelKeys { let holder_channel_pubkeys = InMemoryChannelKeys::make_holder_keys(secp_ctx, &funding_key, &revocation_base_key, &payment_key, &delayed_payment_base_key, @@ -404,7 +402,7 @@ impl InMemoryChannelKeys { channel_value_satoshis, holder_channel_pubkeys, channel_parameters: None, - key_derivation_params, + channel_keys_id, } } @@ -468,7 +466,7 @@ impl ChannelKeys for InMemoryChannelKeys { } fn pubkeys(&self) -> &ChannelPublicKeys { &self.holder_channel_pubkeys } - fn key_derivation_params(&self) -> (u64, u64) { self.key_derivation_params } + fn channel_keys_id(&self) -> [u8; 32] { self.channel_keys_id } fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction, secp_ctx: &Secp256k1) -> Result<(Signature, Vec), ()> { let trusted_tx = commitment_tx.trust(); @@ -600,8 +598,7 @@ impl Writeable for InMemoryChannelKeys { self.commitment_seed.write(writer)?; self.channel_parameters.write(writer)?; self.channel_value_satoshis.write(writer)?; - self.key_derivation_params.0.write(writer)?; - self.key_derivation_params.1.write(writer)?; + self.channel_keys_id.write(writer)?; Ok(()) } @@ -622,8 +619,7 @@ impl Readable for InMemoryChannelKeys { InMemoryChannelKeys::make_holder_keys(&secp_ctx, &funding_key, &revocation_base_key, &payment_key, &delayed_payment_base_key, &htlc_base_key); - let params_1 = Readable::read(reader)?; - let params_2 = Readable::read(reader)?; + let keys_id = Readable::read(reader)?; Ok(InMemoryChannelKeys { funding_key, @@ -635,7 +631,7 @@ impl Readable for InMemoryChannelKeys { channel_value_satoshis, holder_channel_pubkeys, channel_parameters: counterparty_channel_data, - key_derivation_params: (params_1, params_2), + channel_keys_id: keys_id, }) } } @@ -731,19 +727,19 @@ impl KeysManager { /// Derive an old set of ChannelKeys for per-channel secrets based on a key derivation /// parameters. /// Key derivation parameters are accessible through a per-channel secrets - /// ChannelKeys::key_derivation_params and is provided inside DynamicOuputP2WSH in case of + /// ChannelKeys::channel_keys_id and is provided inside DynamicOuputP2WSH in case of /// onchain output detection for which a corresponding delayed_payment_key must be derived. - pub fn derive_channel_keys(&self, channel_value_satoshis: u64, params_1: u64, params_2: u64) -> InMemoryChannelKeys { - let chan_id = ((params_1 & 0xFFFF_FFFF_0000_0000) >> 32) as u32; + pub fn derive_channel_keys(&self, channel_value_satoshis: u64, params: &[u8; 32]) -> InMemoryChannelKeys { + let chan_id = byte_utils::slice_to_be64(¶ms[0..8]); + assert!(chan_id <= std::u32::MAX as u64); // Otherwise the params field wasn't created by us let mut unique_start = Sha256::engine(); - unique_start.input(&byte_utils::be64_to_array(params_2)); - unique_start.input(&byte_utils::be32_to_array(params_1 as u32)); + unique_start.input(params); unique_start.input(&self.seed); // We only seriously intend to rely on the channel_master_key for true secure // entropy, everything else just ensures uniqueness. We rely on the unique_start (ie // starting_time provided in the constructor) to be unique. - let child_privkey = self.channel_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(chan_id).expect("key space exhausted")).expect("Your RNG is busted"); + let child_privkey = self.channel_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(chan_id as u32).expect("key space exhausted")).expect("Your RNG is busted"); unique_start.input(&child_privkey.private_key.key[..]); let seed = Sha256::from_engine(unique_start).into_inner(); @@ -778,7 +774,7 @@ impl KeysManager { htlc_base_key, commitment_seed, channel_value_satoshis, - (params_1, params_2), + params.clone() ) } } @@ -800,8 +796,12 @@ impl KeysInterface for KeysManager { fn get_channel_keys(&self, _inbound: bool, channel_value_satoshis: u64) -> Self::ChanKeySigner { let child_ix = self.channel_child_index.fetch_add(1, Ordering::AcqRel); - let ix_and_nanos: u64 = (child_ix as u64) << 32 | (self.starting_time_nanos as u64); - self.derive_channel_keys(channel_value_satoshis, ix_and_nanos, self.starting_time_secs) + assert!(child_ix <= std::u32::MAX as usize); + let mut id = [0; 32]; + id[0..8].copy_from_slice(&byte_utils::be64_to_array(child_ix as u64)); + id[8..16].copy_from_slice(&byte_utils::be64_to_array(self.starting_time_nanos as u64)); + id[16..24].copy_from_slice(&byte_utils::be64_to_array(self.starting_time_secs)); + self.derive_channel_keys(channel_value_satoshis, &id) } fn get_secure_random_bytes(&self) -> [u8; 32] { diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 08faea160..e700b1f3b 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -4657,7 +4657,7 @@ mod tests { // These aren't set in the test vectors: [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], 10_000_000, - (0, 0) + [0; 32] ); assert_eq!(chan_keys.pubkeys().funding_pubkey.serialize()[..], diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index 77b791e01..4c15a95eb 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -4662,7 +4662,7 @@ macro_rules! check_spendable_outputs { Event::SpendableOutputs { ref outputs } => { for outp in outputs { match *outp { - SpendableOutputDescriptor::StaticOutputCounterpartyPayment { ref outpoint, ref output, ref key_derivation_params } => { + SpendableOutputDescriptor::StaticOutputCounterpartyPayment { ref outpoint, ref output, ref channel_keys_id } => { let input = TxIn { previous_output: outpoint.into_bitcoin_outpoint(), script_sig: Script::new(), @@ -4681,7 +4681,7 @@ macro_rules! check_spendable_outputs { }; spend_tx.output[0].value -= (spend_tx.get_weight() + 2 + 1 + 73 + 35 + 3) as u64 / 4; // (Max weight + 3 (to round up)) / 4 let secp_ctx = Secp256k1::new(); - let keys = $keysinterface.derive_channel_keys($chan_value, key_derivation_params.0, key_derivation_params.1); + let keys = $keysinterface.derive_channel_keys($chan_value, channel_keys_id); let remotepubkey = keys.pubkeys().payment_point; let witness_script = Address::p2pkh(&::bitcoin::PublicKey{compressed: true, key: remotepubkey}, Network::Testnet).script_pubkey(); let sighash = Message::from_slice(&bip143::SigHashCache::new(&spend_tx).signature_hash(0, &witness_script, output.value, SigHashType::All)[..]).unwrap(); @@ -4691,7 +4691,7 @@ macro_rules! check_spendable_outputs { spend_tx.input[0].witness.push(remotepubkey.serialize().to_vec()); txn.push(spend_tx); }, - SpendableOutputDescriptor::DynamicOutputP2WSH { ref outpoint, ref per_commitment_point, ref to_self_delay, ref output, ref key_derivation_params, ref revocation_pubkey } => { + SpendableOutputDescriptor::DynamicOutputP2WSH { ref outpoint, ref per_commitment_point, ref to_self_delay, ref output, ref channel_keys_id, ref revocation_pubkey } => { let input = TxIn { previous_output: outpoint.into_bitcoin_outpoint(), script_sig: Script::new(), @@ -4709,7 +4709,7 @@ macro_rules! check_spendable_outputs { output: vec![outp], }; let secp_ctx = Secp256k1::new(); - let keys = $keysinterface.derive_channel_keys($chan_value, key_derivation_params.0, key_derivation_params.1); + let keys = $keysinterface.derive_channel_keys($chan_value, channel_keys_id); if let Ok(delayed_payment_key) = chan_utils::derive_private_key(&secp_ctx, &per_commitment_point, &keys.inner.delayed_payment_base_key) { let delayed_payment_pubkey = PublicKey::from_secret_key(&secp_ctx, &delayed_payment_key); diff --git a/lightning/src/util/enforcing_trait_impls.rs b/lightning/src/util/enforcing_trait_impls.rs index 88c1754f1..f5d531ca3 100644 --- a/lightning/src/util/enforcing_trait_impls.rs +++ b/lightning/src/util/enforcing_trait_impls.rs @@ -89,7 +89,7 @@ impl ChannelKeys for EnforcingChannelKeys { } fn pubkeys(&self) -> &ChannelPublicKeys { self.inner.pubkeys() } - fn key_derivation_params(&self) -> (u64, u64) { self.inner.key_derivation_params() } + fn channel_keys_id(&self) -> [u8; 32] { self.inner.channel_keys_id() } fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction, secp_ctx: &Secp256k1) -> Result<(Signature, Vec), ()> { self.verify_counterparty_commitment_tx(commitment_tx, secp_ctx); diff --git a/lightning/src/util/test_utils.rs b/lightning/src/util/test_utils.rs index 4bf8aa39d..b758f5c65 100644 --- a/lightning/src/util/test_utils.rs +++ b/lightning/src/util/test_utils.rs @@ -482,8 +482,8 @@ impl TestKeysInterface { revoked_commitments: Mutex::new(HashMap::new()), } } - pub fn derive_channel_keys(&self, channel_value_satoshis: u64, user_id_1: u64, user_id_2: u64) -> EnforcingChannelKeys { - let keys = self.backing.derive_channel_keys(channel_value_satoshis, user_id_1, user_id_2); + pub fn derive_channel_keys(&self, channel_value_satoshis: u64, id: &[u8; 32]) -> EnforcingChannelKeys { + let keys = self.backing.derive_channel_keys(channel_value_satoshis, id); let revoked_commitment = self.make_revoked_commitment_cell(keys.commitment_seed); EnforcingChannelKeys::new_with_revoked(keys, revoked_commitment, self.disable_revocation_policy_check) } From 36cc5814c1802dee2541c52497f8b4f034876daa Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 6 Feb 2021 13:19:40 -0500 Subject: [PATCH 2/5] Expand documentation and fields in SpendableOutputDescriptors This adds a channel_value_satoshis field to SpendableOutputDescriptors as it is required to recreate our InMemoryChannelKeys. It also slightly expands documentation. --- lightning/src/chain/channelmonitor.rs | 4 ++- lightning/src/chain/keysinterface.rs | 36 +++++++++++++++++---------- lightning/src/ln/functional_tests.rs | 8 +++--- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index a8258f564..90f035201 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -2206,8 +2206,9 @@ impl ChannelMonitor { per_commitment_point: broadcasted_holder_revokable_script.1, to_self_delay: self.on_holder_tx_csv, output: outp.clone(), - channel_keys_id: self.channel_keys_id, revocation_pubkey: broadcasted_holder_revokable_script.2.clone(), + channel_keys_id: self.channel_keys_id, + channel_value_satoshis: self.channel_value_satoshis, }); break; } @@ -2216,6 +2217,7 @@ impl ChannelMonitor { outpoint: OutPoint { txid: tx.txid(), index: i as u16 }, output: outp.clone(), channel_keys_id: self.channel_keys_id, + channel_value_satoshis: self.channel_value_satoshis, }); break; } else if outp.script_pubkey == self.shutdown_script { diff --git a/lightning/src/chain/keysinterface.rs b/lightning/src/chain/keysinterface.rs index f713d70ca..a170b072c 100644 --- a/lightning/src/chain/keysinterface.rs +++ b/lightning/src/chain/keysinterface.rs @@ -47,9 +47,9 @@ use ln::msgs::DecodeError; /// that txid/index, and any keys or other information required to sign. #[derive(Clone, Debug, PartialEq)] pub enum SpendableOutputDescriptor { - /// An output to a script which was provided via KeysInterface, thus you should already know - /// how to spend it. No keys are provided as rust-lightning was never given any keys - only the - /// script_pubkey as it appears in the output. + /// An output to a script which was provided via KeysInterface directly, either from + /// `get_destination_script()` or `get_shutdown_pubkey()`, thus you should already know how to + /// spend it. No secret keys are provided as rust-lightning was never given any key. /// These may include outputs from a transaction punishing our counterparty or claiming an HTLC /// on-chain using the payment preimage or after it has timed out. StaticOutput { @@ -98,11 +98,14 @@ pub enum SpendableOutputDescriptor { to_self_delay: u16, /// The output which is referenced by the given outpoint output: TxOut, - /// The channel keys state used to proceed to derivation of signing key. Must - /// be pass to KeysInterface::derive_channel_keys. - channel_keys_id: [u8; 32], /// The revocation_pubkey used to derive witnessScript - revocation_pubkey: PublicKey + revocation_pubkey: PublicKey, + /// Arbitrary identification information returned by a call to + /// `ChannelKeys::channel_keys_id()`. This may be useful in re-deriving keys used in + /// the channel to spend the output. + channel_keys_id: [u8; 32], + /// The value of the channel which this output originated from, possibly indirectly. + channel_value_satoshis: u64, }, /// An output to a P2WPKH, spendable exclusively by our payment key (ie the private key which /// corresponds to the public key in ChannelKeys::pubkeys().payment_point). @@ -116,9 +119,12 @@ pub enum SpendableOutputDescriptor { outpoint: OutPoint, /// The output which is reference by the given outpoint output: TxOut, - /// The channel keys state used to proceed to derivation of signing key. Must - /// be pass to KeysInterface::derive_channel_keys. + /// Arbitrary identification information returned by a call to + /// `ChannelKeys::channel_keys_id()`. This may be useful in re-deriving keys used in + /// the channel to spend the output. channel_keys_id: [u8; 32], + /// The value of the channel which this transactions spends. + channel_value_satoshis: u64, } } @@ -130,20 +136,22 @@ impl Writeable for SpendableOutputDescriptor { outpoint.write(writer)?; output.write(writer)?; }, - &SpendableOutputDescriptor::DynamicOutputP2WSH { ref outpoint, ref per_commitment_point, ref to_self_delay, ref output, ref channel_keys_id, ref revocation_pubkey } => { + &SpendableOutputDescriptor::DynamicOutputP2WSH { ref outpoint, ref per_commitment_point, ref to_self_delay, ref output, ref revocation_pubkey, ref channel_keys_id, channel_value_satoshis } => { 1u8.write(writer)?; outpoint.write(writer)?; per_commitment_point.write(writer)?; to_self_delay.write(writer)?; output.write(writer)?; - channel_keys_id.write(writer)?; revocation_pubkey.write(writer)?; + channel_keys_id.write(writer)?; + channel_value_satoshis.write(writer)?; }, - &SpendableOutputDescriptor::StaticOutputCounterpartyPayment { ref outpoint, ref output, ref channel_keys_id } => { + &SpendableOutputDescriptor::StaticOutputCounterpartyPayment { ref outpoint, ref output, ref channel_keys_id, channel_value_satoshis } => { 2u8.write(writer)?; outpoint.write(writer)?; output.write(writer)?; channel_keys_id.write(writer)?; + channel_value_satoshis.write(writer)?; }, } Ok(()) @@ -162,13 +170,15 @@ impl Readable for SpendableOutputDescriptor { per_commitment_point: Readable::read(reader)?, to_self_delay: Readable::read(reader)?, output: Readable::read(reader)?, - channel_keys_id: Readable::read(reader)?, revocation_pubkey: Readable::read(reader)?, + channel_keys_id: Readable::read(reader)?, + channel_value_satoshis: Readable::read(reader)?, }), 2u8 => Ok(SpendableOutputDescriptor::StaticOutputCounterpartyPayment { outpoint: Readable::read(reader)?, output: Readable::read(reader)?, channel_keys_id: Readable::read(reader)?, + channel_value_satoshis: Readable::read(reader)?, }), _ => Err(DecodeError::InvalidValue), } diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index 4c15a95eb..eef8199e8 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -4662,7 +4662,8 @@ macro_rules! check_spendable_outputs { Event::SpendableOutputs { ref outputs } => { for outp in outputs { match *outp { - SpendableOutputDescriptor::StaticOutputCounterpartyPayment { ref outpoint, ref output, ref channel_keys_id } => { + SpendableOutputDescriptor::StaticOutputCounterpartyPayment { ref outpoint, ref output, ref channel_keys_id, channel_value_satoshis } => { + assert_eq!(channel_value_satoshis, $chan_value); let input = TxIn { previous_output: outpoint.into_bitcoin_outpoint(), script_sig: Script::new(), @@ -4691,7 +4692,8 @@ macro_rules! check_spendable_outputs { spend_tx.input[0].witness.push(remotepubkey.serialize().to_vec()); txn.push(spend_tx); }, - SpendableOutputDescriptor::DynamicOutputP2WSH { ref outpoint, ref per_commitment_point, ref to_self_delay, ref output, ref channel_keys_id, ref revocation_pubkey } => { + SpendableOutputDescriptor::DynamicOutputP2WSH { ref outpoint, ref per_commitment_point, ref to_self_delay, ref output, ref revocation_pubkey, ref channel_keys_id, channel_value_satoshis } => { + assert_eq!(channel_value_satoshis, $chan_value); let input = TxIn { previous_output: outpoint.into_bitcoin_outpoint(), script_sig: Script::new(), @@ -7484,7 +7486,7 @@ fn test_data_loss_protect() { let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42}; connect_block(&nodes[0], &Block { header, txdata: vec![node_txn[0].clone()]}, 0); connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1, 0, true, header.block_hash()); - let spend_txn = check_spendable_outputs!(nodes[0], 1, node_cfgs[0].keys_manager, 100000); + let spend_txn = check_spendable_outputs!(nodes[0], 1, node_cfgs[0].keys_manager, 1000000); assert_eq!(spend_txn.len(), 1); check_spends!(spend_txn[0], node_txn[0]); } From 7dbced3f285dc81cecee5b8ffaeea38f006d9a0c Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Tue, 2 Feb 2021 16:40:59 -0500 Subject: [PATCH 3/5] Slightly expand documentation on KeysInterface Specifically, this notes when methods can or can not return the same value on each call. --- lightning/src/chain/keysinterface.rs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/lightning/src/chain/keysinterface.rs b/lightning/src/chain/keysinterface.rs index a170b072c..da5a99ddb 100644 --- a/lightning/src/chain/keysinterface.rs +++ b/lightning/src/chain/keysinterface.rs @@ -335,18 +335,31 @@ pub trait KeysInterface: Send + Sync { /// A type which implements ChannelKeys which will be returned by get_channel_keys. type ChanKeySigner : ChannelKeys; - /// Get node secret key (aka node_id or network_key) + /// Get node secret key (aka node_id or network_key). + /// + /// This method must return the same value each time it is called. fn get_node_secret(&self) -> SecretKey; - /// Get destination redeemScript to encumber static protocol exit points. + /// Get a script pubkey which we send funds to when claiming on-chain contestable outputs. + /// + /// This method should return a different value each time it is called, to avoid linking + /// on-chain funds across channels as controlled to the same user. fn get_destination_script(&self) -> Script; - /// Get shutdown_pubkey to use as PublicKey at channel closure + /// Get a public key which we will send funds to (in the form of a P2WPKH output) when closing + /// a channel. + /// + /// This method should return a different value each time it is called, to avoid linking + /// on-chain funds across channels as controlled to the same user. fn get_shutdown_pubkey(&self) -> PublicKey; /// Get a new set of ChannelKeys for per-channel secrets. These MUST be unique even if you /// restarted with some stale data! + /// + /// This method must return a different value each time it is called. fn get_channel_keys(&self, inbound: bool, channel_value_satoshis: u64) -> Self::ChanKeySigner; /// Gets a unique, cryptographically-secure, random 32 byte value. This is used for encrypting /// onion packets and for temporary channel IDs. There is no requirement that these be /// persisted anywhere, though they must be unique across restarts. + /// + /// This method must return a different value each time it is called. fn get_secure_random_bytes(&self) -> [u8; 32]; /// Reads a `ChanKeySigner` for this `KeysInterface` from the given input stream. From e9d819dce891f649cae57b870e4ae01c57bc2e9b Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 12 Feb 2021 18:58:59 -0500 Subject: [PATCH 4/5] Update auto-generated bindings --- lightning-c-bindings/include/lightning.h | 68 +++++----- lightning-c-bindings/include/lightningpp.hpp | 63 ++++----- lightning-c-bindings/src/c_types/derived.rs | 35 ----- .../src/chain/keysinterface.rs | 126 ++++++++++-------- 4 files changed, 131 insertions(+), 161 deletions(-) diff --git a/lightning-c-bindings/include/lightning.h b/lightning-c-bindings/include/lightning.h index 2025fdf4f..d8299b407 100644 --- a/lightning-c-bindings/include/lightning.h +++ b/lightning-c-bindings/include/lightning.h @@ -241,10 +241,13 @@ typedef struct LDKPublicKey { uint8_t compressed_form[33]; } LDKPublicKey; -typedef struct LDKC2Tuple_u64u64Z { - uint64_t a; - uint64_t b; -} LDKC2Tuple_u64u64Z; +/** + * Arbitrary 32 bytes, which could represent one of a few different things. You probably want to + * look up the corresponding function in rust-lightning's docs. + */ +typedef struct LDKThirtyTwoBytes { + uint8_t data[32]; +} LDKThirtyTwoBytes; /** * When on-chain outputs are created by rust-lightning (which our counterparty is not able to @@ -255,9 +258,9 @@ typedef struct LDKC2Tuple_u64u64Z { */ typedef enum LDKSpendableOutputDescriptor_Tag { /** - * An output to a script which was provided via KeysInterface, thus you should already know - * how to spend it. No keys are provided as rust-lightning was never given any keys - only the - * script_pubkey as it appears in the output. + * An output to a script which was provided via KeysInterface directly, either from + * `get_destination_script()` or `get_shutdown_pubkey()`, thus you should already know how to + * spend it. No secret keys are provided as rust-lightning was never given any key. * These may include outputs from a transaction punishing our counterparty or claiming an HTLC * on-chain using the payment preimage or after it has timed out. */ @@ -319,14 +322,16 @@ typedef struct LDKSpendableOutputDescriptor_LDKDynamicOutputP2WSH_Body { struct LDKPublicKey per_commitment_point; uint16_t to_self_delay; struct LDKTxOut output; - struct LDKC2Tuple_u64u64Z key_derivation_params; struct LDKPublicKey revocation_pubkey; + struct LDKThirtyTwoBytes channel_keys_id; + uint64_t channel_value_satoshis; } LDKSpendableOutputDescriptor_LDKDynamicOutputP2WSH_Body; typedef struct LDKSpendableOutputDescriptor_LDKStaticOutputCounterpartyPayment_Body { struct LDKOutPoint outpoint; struct LDKTxOut output; - struct LDKC2Tuple_u64u64Z key_derivation_params; + struct LDKThirtyTwoBytes channel_keys_id; + uint64_t channel_value_satoshis; } LDKSpendableOutputDescriptor_LDKStaticOutputCounterpartyPayment_Body; typedef struct MUST_USE_STRUCT LDKSpendableOutputDescriptor { @@ -889,14 +894,6 @@ typedef struct LDKCVec_MessageSendEventZ { uintptr_t datalen; } LDKCVec_MessageSendEventZ; -/** - * Arbitrary 32 bytes, which could represent one of a few different things. You probably want to - * look up the corresponding function in rust-lightning's docs. - */ -typedef struct LDKThirtyTwoBytes { - uint8_t data[32]; -} LDKThirtyTwoBytes; - /** * An Event which you should probably take some action in response to. * @@ -1349,11 +1346,11 @@ typedef struct LDKChannelKeys { */ void (*set_pubkeys)(const struct LDKChannelKeys*NONNULL_PTR ); /** - * Gets arbitrary identifiers describing the set of keys which are provided back to you in - * some SpendableOutputDescriptor types. These should be sufficient to identify this + * Gets an arbitrary identifier describing the set of keys which are provided back to you in + * some SpendableOutputDescriptor types. This should be sufficient to identify this * ChannelKeys object uniquely and lookup or re-derive its keys. */ - struct LDKC2Tuple_u64u64Z (*key_derivation_params)(const void *this_arg); + struct LDKThirtyTwoBytes (*channel_keys_id)(const void *this_arg); /** * Create a signature for a counterparty's commitment transaction and associated HTLC transactions. * @@ -1849,26 +1846,39 @@ typedef struct LDKu8slice { typedef struct LDKKeysInterface { void *this_arg; /** - * Get node secret key (aka node_id or network_key) + * Get node secret key (aka node_id or network_key). + * + * This method must return the same value each time it is called. */ struct LDKSecretKey (*get_node_secret)(const void *this_arg); /** - * Get destination redeemScript to encumber static protocol exit points. + * Get a script pubkey which we send funds to when claiming on-chain contestable outputs. + * + * This method should return a different value each time it is called, to avoid linking + * on-chain funds across channels as controlled to the same user. */ struct LDKCVec_u8Z (*get_destination_script)(const void *this_arg); /** - * Get shutdown_pubkey to use as PublicKey at channel closure + * Get a public key which we will send funds to (in the form of a P2WPKH output) when closing + * a channel. + * + * This method should return a different value each time it is called, to avoid linking + * on-chain funds across channels as controlled to the same user. */ struct LDKPublicKey (*get_shutdown_pubkey)(const void *this_arg); /** * Get a new set of ChannelKeys for per-channel secrets. These MUST be unique even if you * restarted with some stale data! + * + * This method must return a different value each time it is called. */ struct LDKChannelKeys (*get_channel_keys)(const void *this_arg, bool inbound, uint64_t channel_value_satoshis); /** * Gets a unique, cryptographically-secure, random 32 byte value. This is used for encrypting * onion packets and for temporary channel IDs. There is no requirement that these be * persisted anywhere, though they must be unique across restarts. + * + * This method must return a different value each time it is called. */ struct LDKThirtyTwoBytes (*get_secure_random_bytes)(const void *this_arg); /** @@ -3548,12 +3558,6 @@ struct LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ CResult_C2Tuple_B void CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ_free(struct LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ _res); -struct LDKC2Tuple_u64u64Z C2Tuple_u64u64Z_clone(const struct LDKC2Tuple_u64u64Z *NONNULL_PTR orig); - -struct LDKC2Tuple_u64u64Z C2Tuple_u64u64Z_new(uint64_t a, uint64_t b); - -void C2Tuple_u64u64Z_free(struct LDKC2Tuple_u64u64Z _res); - struct LDKCResult_SpendableOutputDescriptorDecodeErrorZ CResult_SpendableOutputDescriptorDecodeErrorZ_ok(struct LDKSpendableOutputDescriptor o); struct LDKCResult_SpendableOutputDescriptorDecodeErrorZ CResult_SpendableOutputDescriptorDecodeErrorZ_err(struct LDKDecodeError e); @@ -4686,7 +4690,7 @@ void InMemoryChannelKeys_set_commitment_seed(struct LDKInMemoryChannelKeys *NONN /** * Create a new InMemoryChannelKeys */ -MUST_USE_RES struct LDKInMemoryChannelKeys InMemoryChannelKeys_new(struct LDKSecretKey funding_key, struct LDKSecretKey revocation_base_key, struct LDKSecretKey payment_key, struct LDKSecretKey delayed_payment_base_key, struct LDKSecretKey htlc_base_key, struct LDKThirtyTwoBytes commitment_seed, uint64_t channel_value_satoshis, struct LDKC2Tuple_u64u64Z key_derivation_params); +MUST_USE_RES struct LDKInMemoryChannelKeys InMemoryChannelKeys_new(struct LDKSecretKey funding_key, struct LDKSecretKey revocation_base_key, struct LDKSecretKey payment_key, struct LDKSecretKey delayed_payment_base_key, struct LDKSecretKey htlc_base_key, struct LDKThirtyTwoBytes commitment_seed, uint64_t channel_value_satoshis, struct LDKThirtyTwoBytes channel_keys_id); /** * Counterparty pubkeys. @@ -4765,10 +4769,10 @@ MUST_USE_RES struct LDKKeysManager KeysManager_new(const uint8_t (*seed)[32], en * Derive an old set of ChannelKeys for per-channel secrets based on a key derivation * parameters. * Key derivation parameters are accessible through a per-channel secrets - * ChannelKeys::key_derivation_params and is provided inside DynamicOuputP2WSH in case of + * ChannelKeys::channel_keys_id and is provided inside DynamicOuputP2WSH in case of * onchain output detection for which a corresponding delayed_payment_key must be derived. */ -MUST_USE_RES struct LDKInMemoryChannelKeys KeysManager_derive_channel_keys(const struct LDKKeysManager *NONNULL_PTR this_arg, uint64_t channel_value_satoshis, uint64_t params_1, uint64_t params_2); +MUST_USE_RES struct LDKInMemoryChannelKeys KeysManager_derive_channel_keys(const struct LDKKeysManager *NONNULL_PTR this_arg, uint64_t channel_value_satoshis, const uint8_t (*params)[32]); struct LDKKeysInterface KeysManager_as_KeysInterface(const struct LDKKeysManager *NONNULL_PTR this_arg); diff --git a/lightning-c-bindings/include/lightningpp.hpp b/lightning-c-bindings/include/lightningpp.hpp index 4e4fbb46a..2d6473086 100644 --- a/lightning-c-bindings/include/lightningpp.hpp +++ b/lightning-c-bindings/include/lightningpp.hpp @@ -2096,21 +2096,6 @@ public: const LDKCVec_PublicKeyZ* operator &() const { return &self; } const LDKCVec_PublicKeyZ* operator ->() const { return &self; } }; -class C2Tuple_u64u64Z { -private: - LDKC2Tuple_u64u64Z self; -public: - C2Tuple_u64u64Z(const C2Tuple_u64u64Z&) = delete; - C2Tuple_u64u64Z(C2Tuple_u64u64Z&& o) : self(o.self) { memset(&o, 0, sizeof(C2Tuple_u64u64Z)); } - C2Tuple_u64u64Z(LDKC2Tuple_u64u64Z&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKC2Tuple_u64u64Z)); } - operator LDKC2Tuple_u64u64Z() && { LDKC2Tuple_u64u64Z res = self; memset(&self, 0, sizeof(LDKC2Tuple_u64u64Z)); return res; } - ~C2Tuple_u64u64Z() { C2Tuple_u64u64Z_free(self); } - C2Tuple_u64u64Z& operator=(C2Tuple_u64u64Z&& o) { C2Tuple_u64u64Z_free(self); self = o.self; memset(&o, 0, sizeof(C2Tuple_u64u64Z)); return *this; } - LDKC2Tuple_u64u64Z* operator &() { return &self; } - LDKC2Tuple_u64u64Z* operator ->() { return &self; } - const LDKC2Tuple_u64u64Z* operator &() const { return &self; } - const LDKC2Tuple_u64u64Z* operator ->() const { return &self; } -}; class C2Tuple_u32TxOutZ { private: LDKC2Tuple_u32TxOutZ self; @@ -2576,20 +2561,20 @@ public: const LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ* operator &() const { return &self; } const LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ* operator ->() const { return &self; } }; -class CVec_UpdateFailHTLCZ { +class CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ { private: - LDKCVec_UpdateFailHTLCZ self; + LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ self; public: - CVec_UpdateFailHTLCZ(const CVec_UpdateFailHTLCZ&) = delete; - CVec_UpdateFailHTLCZ(CVec_UpdateFailHTLCZ&& o) : self(o.self) { memset(&o, 0, sizeof(CVec_UpdateFailHTLCZ)); } - CVec_UpdateFailHTLCZ(LDKCVec_UpdateFailHTLCZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCVec_UpdateFailHTLCZ)); } - operator LDKCVec_UpdateFailHTLCZ() && { LDKCVec_UpdateFailHTLCZ res = self; memset(&self, 0, sizeof(LDKCVec_UpdateFailHTLCZ)); return res; } - ~CVec_UpdateFailHTLCZ() { CVec_UpdateFailHTLCZ_free(self); } - CVec_UpdateFailHTLCZ& operator=(CVec_UpdateFailHTLCZ&& o) { CVec_UpdateFailHTLCZ_free(self); self = o.self; memset(&o, 0, sizeof(CVec_UpdateFailHTLCZ)); return *this; } - LDKCVec_UpdateFailHTLCZ* operator &() { return &self; } - LDKCVec_UpdateFailHTLCZ* operator ->() { return &self; } - const LDKCVec_UpdateFailHTLCZ* operator &() const { return &self; } - const LDKCVec_UpdateFailHTLCZ* operator ->() const { return &self; } + CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ(const CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ&) = delete; + CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ(CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ&& o) : self(o.self) { memset(&o, 0, sizeof(CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ)); } + CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ(LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ)); } + operator LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ() && { LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ res = self; memset(&self, 0, sizeof(LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ)); return res; } + ~CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ() { CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ_free(self); } + CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ& operator=(CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ&& o) { CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ_free(self); self = o.self; memset(&o, 0, sizeof(CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ)); return *this; } + LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ* operator &() { return &self; } + LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ* operator ->() { return &self; } + const LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ* operator &() const { return &self; } + const LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ* operator ->() const { return &self; } }; class C2Tuple_OutPointScriptZ { private: @@ -2621,20 +2606,20 @@ public: const LDKCResult_InMemoryChannelKeysDecodeErrorZ* operator &() const { return &self; } const LDKCResult_InMemoryChannelKeysDecodeErrorZ* operator ->() const { return &self; } }; -class CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ { +class CVec_UpdateFailHTLCZ { private: - LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ self; + LDKCVec_UpdateFailHTLCZ self; public: - CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ(const CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ&) = delete; - CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ(CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ&& o) : self(o.self) { memset(&o, 0, sizeof(CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ)); } - CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ(LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ)); } - operator LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ() && { LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ res = self; memset(&self, 0, sizeof(LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ)); return res; } - ~CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ() { CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ_free(self); } - CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ& operator=(CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ&& o) { CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ_free(self); self = o.self; memset(&o, 0, sizeof(CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ)); return *this; } - LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ* operator &() { return &self; } - LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ* operator ->() { return &self; } - const LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ* operator &() const { return &self; } - const LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ* operator ->() const { return &self; } + CVec_UpdateFailHTLCZ(const CVec_UpdateFailHTLCZ&) = delete; + CVec_UpdateFailHTLCZ(CVec_UpdateFailHTLCZ&& o) : self(o.self) { memset(&o, 0, sizeof(CVec_UpdateFailHTLCZ)); } + CVec_UpdateFailHTLCZ(LDKCVec_UpdateFailHTLCZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCVec_UpdateFailHTLCZ)); } + operator LDKCVec_UpdateFailHTLCZ() && { LDKCVec_UpdateFailHTLCZ res = self; memset(&self, 0, sizeof(LDKCVec_UpdateFailHTLCZ)); return res; } + ~CVec_UpdateFailHTLCZ() { CVec_UpdateFailHTLCZ_free(self); } + CVec_UpdateFailHTLCZ& operator=(CVec_UpdateFailHTLCZ&& o) { CVec_UpdateFailHTLCZ_free(self); self = o.self; memset(&o, 0, sizeof(CVec_UpdateFailHTLCZ)); return *this; } + LDKCVec_UpdateFailHTLCZ* operator &() { return &self; } + LDKCVec_UpdateFailHTLCZ* operator ->() { return &self; } + const LDKCVec_UpdateFailHTLCZ* operator &() const { return &self; } + const LDKCVec_UpdateFailHTLCZ* operator ->() const { return &self; } }; class CResult_RouteDecodeErrorZ { private: diff --git a/lightning-c-bindings/src/c_types/derived.rs b/lightning-c-bindings/src/c_types/derived.rs index 6f703a5b1..d30163e60 100644 --- a/lightning-c-bindings/src/c_types/derived.rs +++ b/lightning-c-bindings/src/c_types/derived.rs @@ -711,41 +711,6 @@ impl From for C2Tuple_u64u64Z { - fn from (tup: (u64, u64)) -> Self { - Self { - a: tup.0, - b: tup.1, - } - } -} -impl C2Tuple_u64u64Z { - #[allow(unused)] pub(crate) fn to_rust(mut self) -> (u64, u64) { - (self.a, self.b) - } -} -impl Clone for C2Tuple_u64u64Z { - fn clone(&self) -> Self { - Self { - a: self.a.clone(), - b: self.b.clone(), - } - } -} -#[no_mangle] -pub extern "C" fn C2Tuple_u64u64Z_clone(orig: &C2Tuple_u64u64Z) -> C2Tuple_u64u64Z { orig.clone() } -#[no_mangle] -pub extern "C" fn C2Tuple_u64u64Z_new(a: u64, b: u64) -> C2Tuple_u64u64Z { - C2Tuple_u64u64Z { a, b, } -} - -#[no_mangle] -pub extern "C" fn C2Tuple_u64u64Z_free(_res: C2Tuple_u64u64Z) { } -#[repr(C)] pub union CResult_SpendableOutputDescriptorDecodeErrorZPtr { pub result: *mut crate::chain::keysinterface::SpendableOutputDescriptor, pub err: *mut crate::ln::msgs::DecodeError, diff --git a/lightning-c-bindings/src/chain/keysinterface.rs b/lightning-c-bindings/src/chain/keysinterface.rs index cef2cdd4d..37758e8bc 100644 --- a/lightning-c-bindings/src/chain/keysinterface.rs +++ b/lightning-c-bindings/src/chain/keysinterface.rs @@ -15,9 +15,9 @@ use crate::c_types::*; #[derive(Clone)] #[repr(C)] pub enum SpendableOutputDescriptor { - /// An output to a script which was provided via KeysInterface, thus you should already know - /// how to spend it. No keys are provided as rust-lightning was never given any keys - only the - /// script_pubkey as it appears in the output. + /// An output to a script which was provided via KeysInterface directly, either from + /// `get_destination_script()` or `get_shutdown_pubkey()`, thus you should already know how to + /// spend it. No secret keys are provided as rust-lightning was never given any key. /// These may include outputs from a transaction punishing our counterparty or claiming an HTLC /// on-chain using the payment preimage or after it has timed out. StaticOutput { @@ -57,8 +57,9 @@ pub enum SpendableOutputDescriptor { per_commitment_point: crate::c_types::PublicKey, to_self_delay: u16, output: crate::c_types::TxOut, - key_derivation_params: crate::c_types::derived::C2Tuple_u64u64Z, revocation_pubkey: crate::c_types::PublicKey, + channel_keys_id: crate::c_types::ThirtyTwoBytes, + channel_value_satoshis: u64, }, /// An output to a P2WPKH, spendable exclusively by our payment key (ie the private key which /// corresponds to the public key in ChannelKeys::pubkeys().payment_point). @@ -70,7 +71,8 @@ pub enum SpendableOutputDescriptor { StaticOutputCounterpartyPayment { outpoint: crate::chain::transaction::OutPoint, output: crate::c_types::TxOut, - key_derivation_params: crate::c_types::derived::C2Tuple_u64u64Z, + channel_keys_id: crate::c_types::ThirtyTwoBytes, + channel_value_satoshis: u64, }, } use lightning::chain::keysinterface::SpendableOutputDescriptor as nativeSpendableOutputDescriptor; @@ -86,32 +88,34 @@ impl SpendableOutputDescriptor { output: output_nonref.into_rust(), } }, - SpendableOutputDescriptor::DynamicOutputP2WSH {ref outpoint, ref per_commitment_point, ref to_self_delay, ref output, ref key_derivation_params, ref revocation_pubkey, } => { + SpendableOutputDescriptor::DynamicOutputP2WSH {ref outpoint, ref per_commitment_point, ref to_self_delay, ref output, ref revocation_pubkey, ref channel_keys_id, ref channel_value_satoshis, } => { let mut outpoint_nonref = (*outpoint).clone(); let mut per_commitment_point_nonref = (*per_commitment_point).clone(); let mut to_self_delay_nonref = (*to_self_delay).clone(); let mut output_nonref = (*output).clone(); - let mut key_derivation_params_nonref = (*key_derivation_params).clone(); - let (mut orig_key_derivation_params_nonref_0, mut orig_key_derivation_params_nonref_1) = key_derivation_params_nonref.to_rust(); let mut local_key_derivation_params_nonref = (orig_key_derivation_params_nonref_0, orig_key_derivation_params_nonref_1); let mut revocation_pubkey_nonref = (*revocation_pubkey).clone(); + let mut channel_keys_id_nonref = (*channel_keys_id).clone(); + let mut channel_value_satoshis_nonref = (*channel_value_satoshis).clone(); nativeSpendableOutputDescriptor::DynamicOutputP2WSH { outpoint: *unsafe { Box::from_raw(outpoint_nonref.take_inner()) }, per_commitment_point: per_commitment_point_nonref.into_rust(), to_self_delay: to_self_delay_nonref, output: output_nonref.into_rust(), - key_derivation_params: local_key_derivation_params_nonref, revocation_pubkey: revocation_pubkey_nonref.into_rust(), + channel_keys_id: channel_keys_id_nonref.data, + channel_value_satoshis: channel_value_satoshis_nonref, } }, - SpendableOutputDescriptor::StaticOutputCounterpartyPayment {ref outpoint, ref output, ref key_derivation_params, } => { + SpendableOutputDescriptor::StaticOutputCounterpartyPayment {ref outpoint, ref output, ref channel_keys_id, ref channel_value_satoshis, } => { let mut outpoint_nonref = (*outpoint).clone(); let mut output_nonref = (*output).clone(); - let mut key_derivation_params_nonref = (*key_derivation_params).clone(); - let (mut orig_key_derivation_params_nonref_0, mut orig_key_derivation_params_nonref_1) = key_derivation_params_nonref.to_rust(); let mut local_key_derivation_params_nonref = (orig_key_derivation_params_nonref_0, orig_key_derivation_params_nonref_1); + let mut channel_keys_id_nonref = (*channel_keys_id).clone(); + let mut channel_value_satoshis_nonref = (*channel_value_satoshis).clone(); nativeSpendableOutputDescriptor::StaticOutputCounterpartyPayment { outpoint: *unsafe { Box::from_raw(outpoint_nonref.take_inner()) }, output: output_nonref.into_rust(), - key_derivation_params: local_key_derivation_params_nonref, + channel_keys_id: channel_keys_id_nonref.data, + channel_value_satoshis: channel_value_satoshis_nonref, } }, } @@ -125,23 +129,23 @@ impl SpendableOutputDescriptor { output: output.into_rust(), } }, - SpendableOutputDescriptor::DynamicOutputP2WSH {mut outpoint, mut per_commitment_point, mut to_self_delay, mut output, mut key_derivation_params, mut revocation_pubkey, } => { - let (mut orig_key_derivation_params_0, mut orig_key_derivation_params_1) = key_derivation_params.to_rust(); let mut local_key_derivation_params = (orig_key_derivation_params_0, orig_key_derivation_params_1); + SpendableOutputDescriptor::DynamicOutputP2WSH {mut outpoint, mut per_commitment_point, mut to_self_delay, mut output, mut revocation_pubkey, mut channel_keys_id, mut channel_value_satoshis, } => { nativeSpendableOutputDescriptor::DynamicOutputP2WSH { outpoint: *unsafe { Box::from_raw(outpoint.take_inner()) }, per_commitment_point: per_commitment_point.into_rust(), to_self_delay: to_self_delay, output: output.into_rust(), - key_derivation_params: local_key_derivation_params, revocation_pubkey: revocation_pubkey.into_rust(), + channel_keys_id: channel_keys_id.data, + channel_value_satoshis: channel_value_satoshis, } }, - SpendableOutputDescriptor::StaticOutputCounterpartyPayment {mut outpoint, mut output, mut key_derivation_params, } => { - let (mut orig_key_derivation_params_0, mut orig_key_derivation_params_1) = key_derivation_params.to_rust(); let mut local_key_derivation_params = (orig_key_derivation_params_0, orig_key_derivation_params_1); + SpendableOutputDescriptor::StaticOutputCounterpartyPayment {mut outpoint, mut output, mut channel_keys_id, mut channel_value_satoshis, } => { nativeSpendableOutputDescriptor::StaticOutputCounterpartyPayment { outpoint: *unsafe { Box::from_raw(outpoint.take_inner()) }, output: output.into_rust(), - key_derivation_params: local_key_derivation_params, + channel_keys_id: channel_keys_id.data, + channel_value_satoshis: channel_value_satoshis, } }, } @@ -157,32 +161,34 @@ impl SpendableOutputDescriptor { output: crate::c_types::TxOut::from_rust(output_nonref), } }, - nativeSpendableOutputDescriptor::DynamicOutputP2WSH {ref outpoint, ref per_commitment_point, ref to_self_delay, ref output, ref key_derivation_params, ref revocation_pubkey, } => { + nativeSpendableOutputDescriptor::DynamicOutputP2WSH {ref outpoint, ref per_commitment_point, ref to_self_delay, ref output, ref revocation_pubkey, ref channel_keys_id, ref channel_value_satoshis, } => { let mut outpoint_nonref = (*outpoint).clone(); let mut per_commitment_point_nonref = (*per_commitment_point).clone(); let mut to_self_delay_nonref = (*to_self_delay).clone(); let mut output_nonref = (*output).clone(); - let mut key_derivation_params_nonref = (*key_derivation_params).clone(); - let (mut orig_key_derivation_params_nonref_0, mut orig_key_derivation_params_nonref_1) = key_derivation_params_nonref; let mut local_key_derivation_params_nonref = (orig_key_derivation_params_nonref_0, orig_key_derivation_params_nonref_1).into(); let mut revocation_pubkey_nonref = (*revocation_pubkey).clone(); + let mut channel_keys_id_nonref = (*channel_keys_id).clone(); + let mut channel_value_satoshis_nonref = (*channel_value_satoshis).clone(); SpendableOutputDescriptor::DynamicOutputP2WSH { outpoint: crate::chain::transaction::OutPoint { inner: Box::into_raw(Box::new(outpoint_nonref)), is_owned: true }, per_commitment_point: crate::c_types::PublicKey::from_rust(&per_commitment_point_nonref), to_self_delay: to_self_delay_nonref, output: crate::c_types::TxOut::from_rust(output_nonref), - key_derivation_params: local_key_derivation_params_nonref, revocation_pubkey: crate::c_types::PublicKey::from_rust(&revocation_pubkey_nonref), + channel_keys_id: crate::c_types::ThirtyTwoBytes { data: channel_keys_id_nonref }, + channel_value_satoshis: channel_value_satoshis_nonref, } }, - nativeSpendableOutputDescriptor::StaticOutputCounterpartyPayment {ref outpoint, ref output, ref key_derivation_params, } => { + nativeSpendableOutputDescriptor::StaticOutputCounterpartyPayment {ref outpoint, ref output, ref channel_keys_id, ref channel_value_satoshis, } => { let mut outpoint_nonref = (*outpoint).clone(); let mut output_nonref = (*output).clone(); - let mut key_derivation_params_nonref = (*key_derivation_params).clone(); - let (mut orig_key_derivation_params_nonref_0, mut orig_key_derivation_params_nonref_1) = key_derivation_params_nonref; let mut local_key_derivation_params_nonref = (orig_key_derivation_params_nonref_0, orig_key_derivation_params_nonref_1).into(); + let mut channel_keys_id_nonref = (*channel_keys_id).clone(); + let mut channel_value_satoshis_nonref = (*channel_value_satoshis).clone(); SpendableOutputDescriptor::StaticOutputCounterpartyPayment { outpoint: crate::chain::transaction::OutPoint { inner: Box::into_raw(Box::new(outpoint_nonref)), is_owned: true }, output: crate::c_types::TxOut::from_rust(output_nonref), - key_derivation_params: local_key_derivation_params_nonref, + channel_keys_id: crate::c_types::ThirtyTwoBytes { data: channel_keys_id_nonref }, + channel_value_satoshis: channel_value_satoshis_nonref, } }, } @@ -196,23 +202,23 @@ impl SpendableOutputDescriptor { output: crate::c_types::TxOut::from_rust(output), } }, - nativeSpendableOutputDescriptor::DynamicOutputP2WSH {mut outpoint, mut per_commitment_point, mut to_self_delay, mut output, mut key_derivation_params, mut revocation_pubkey, } => { - let (mut orig_key_derivation_params_0, mut orig_key_derivation_params_1) = key_derivation_params; let mut local_key_derivation_params = (orig_key_derivation_params_0, orig_key_derivation_params_1).into(); + nativeSpendableOutputDescriptor::DynamicOutputP2WSH {mut outpoint, mut per_commitment_point, mut to_self_delay, mut output, mut revocation_pubkey, mut channel_keys_id, mut channel_value_satoshis, } => { SpendableOutputDescriptor::DynamicOutputP2WSH { outpoint: crate::chain::transaction::OutPoint { inner: Box::into_raw(Box::new(outpoint)), is_owned: true }, per_commitment_point: crate::c_types::PublicKey::from_rust(&per_commitment_point), to_self_delay: to_self_delay, output: crate::c_types::TxOut::from_rust(output), - key_derivation_params: local_key_derivation_params, revocation_pubkey: crate::c_types::PublicKey::from_rust(&revocation_pubkey), + channel_keys_id: crate::c_types::ThirtyTwoBytes { data: channel_keys_id }, + channel_value_satoshis: channel_value_satoshis, } }, - nativeSpendableOutputDescriptor::StaticOutputCounterpartyPayment {mut outpoint, mut output, mut key_derivation_params, } => { - let (mut orig_key_derivation_params_0, mut orig_key_derivation_params_1) = key_derivation_params; let mut local_key_derivation_params = (orig_key_derivation_params_0, orig_key_derivation_params_1).into(); + nativeSpendableOutputDescriptor::StaticOutputCounterpartyPayment {mut outpoint, mut output, mut channel_keys_id, mut channel_value_satoshis, } => { SpendableOutputDescriptor::StaticOutputCounterpartyPayment { outpoint: crate::chain::transaction::OutPoint { inner: Box::into_raw(Box::new(outpoint)), is_owned: true }, output: crate::c_types::TxOut::from_rust(output), - key_derivation_params: local_key_derivation_params, + channel_keys_id: crate::c_types::ThirtyTwoBytes { data: channel_keys_id }, + channel_value_satoshis: channel_value_satoshis, } }, } @@ -281,11 +287,11 @@ pub struct ChannelKeys { /// Note that this takes a pointer to this object, not the this_ptr like other methods do /// This function pointer may be NULL if pubkeys is filled in when this object is created and never needs updating. pub set_pubkeys: Option, - /// Gets arbitrary identifiers describing the set of keys which are provided back to you in - /// some SpendableOutputDescriptor types. These should be sufficient to identify this + /// Gets an arbitrary identifier describing the set of keys which are provided back to you in + /// some SpendableOutputDescriptor types. This should be sufficient to identify this /// ChannelKeys object uniquely and lookup or re-derive its keys. #[must_use] - pub key_derivation_params: extern "C" fn (this_arg: *const c_void) -> crate::c_types::derived::C2Tuple_u64u64Z, + pub channel_keys_id: extern "C" fn (this_arg: *const c_void) -> crate::c_types::ThirtyTwoBytes, /// Create a signature for a counterparty's commitment transaction and associated HTLC transactions. /// /// Note that if signing fails or is rejected, the channel will be force-closed. @@ -381,7 +387,7 @@ pub extern "C" fn ChannelKeys_clone(orig: &ChannelKeys) -> ChannelKeys { release_commitment_secret: orig.release_commitment_secret.clone(), pubkeys: orig.pubkeys.clone(), set_pubkeys: orig.set_pubkeys.clone(), - key_derivation_params: orig.key_derivation_params.clone(), + channel_keys_id: orig.channel_keys_id.clone(), sign_counterparty_commitment: orig.sign_counterparty_commitment.clone(), sign_holder_commitment_and_htlcs: orig.sign_holder_commitment_and_htlcs.clone(), sign_justice_transaction: orig.sign_justice_transaction.clone(), @@ -422,10 +428,9 @@ impl rustChannelKeys for ChannelKeys { } unsafe { &*self.pubkeys.inner } } - fn key_derivation_params(&self) -> (u64, u64) { - let mut ret = (self.key_derivation_params)(self.this_arg); - let (mut orig_ret_0, mut orig_ret_1) = ret.to_rust(); let mut local_ret = (orig_ret_0, orig_ret_1); - local_ret + fn channel_keys_id(&self) -> [u8; 32] { + let mut ret = (self.channel_keys_id)(self.this_arg); + ret.data } fn sign_counterparty_commitment(&self, commitment_tx: &lightning::ln::chan_utils::CommitmentTransaction, _secp_ctx: &bitcoin::secp256k1::Secp256k1) -> Result<(bitcoin::secp256k1::Signature, Vec), ()> { let mut ret = (self.sign_counterparty_commitment)(self.this_arg, &crate::ln::chan_utils::CommitmentTransaction { inner: unsafe { (commitment_tx as *const _) as *mut _ }, is_owned: false }); @@ -488,22 +493,35 @@ impl Drop for ChannelKeys { #[repr(C)] pub struct KeysInterface { pub this_arg: *mut c_void, - /// Get node secret key (aka node_id or network_key) + /// Get node secret key (aka node_id or network_key). + /// + /// This method must return the same value each time it is called. #[must_use] pub get_node_secret: extern "C" fn (this_arg: *const c_void) -> crate::c_types::SecretKey, - /// Get destination redeemScript to encumber static protocol exit points. + /// Get a script pubkey which we send funds to when claiming on-chain contestable outputs. + /// + /// This method should return a different value each time it is called, to avoid linking + /// on-chain funds across channels as controlled to the same user. #[must_use] pub get_destination_script: extern "C" fn (this_arg: *const c_void) -> crate::c_types::derived::CVec_u8Z, - /// Get shutdown_pubkey to use as PublicKey at channel closure + /// Get a public key which we will send funds to (in the form of a P2WPKH output) when closing + /// a channel. + /// + /// This method should return a different value each time it is called, to avoid linking + /// on-chain funds across channels as controlled to the same user. #[must_use] pub get_shutdown_pubkey: extern "C" fn (this_arg: *const c_void) -> crate::c_types::PublicKey, /// Get a new set of ChannelKeys for per-channel secrets. These MUST be unique even if you /// restarted with some stale data! + /// + /// This method must return a different value each time it is called. #[must_use] pub get_channel_keys: extern "C" fn (this_arg: *const c_void, inbound: bool, channel_value_satoshis: u64) -> crate::chain::keysinterface::ChannelKeys, /// Gets a unique, cryptographically-secure, random 32 byte value. This is used for encrypting /// onion packets and for temporary channel IDs. There is no requirement that these be /// persisted anywhere, though they must be unique across restarts. + /// + /// This method must return a different value each time it is called. #[must_use] pub get_secure_random_bytes: extern "C" fn (this_arg: *const c_void) -> crate::c_types::ThirtyTwoBytes, /// Reads a `ChanKeySigner` for this `KeysInterface` from the given input stream. @@ -696,9 +714,8 @@ pub extern "C" fn InMemoryChannelKeys_set_commitment_seed(this_ptr: &mut InMemor /// Create a new InMemoryChannelKeys #[must_use] #[no_mangle] -pub extern "C" fn InMemoryChannelKeys_new(mut funding_key: crate::c_types::SecretKey, mut revocation_base_key: crate::c_types::SecretKey, mut payment_key: crate::c_types::SecretKey, mut delayed_payment_base_key: crate::c_types::SecretKey, mut htlc_base_key: crate::c_types::SecretKey, mut commitment_seed: crate::c_types::ThirtyTwoBytes, mut channel_value_satoshis: u64, mut key_derivation_params: crate::c_types::derived::C2Tuple_u64u64Z) -> crate::chain::keysinterface::InMemoryChannelKeys { - let (mut orig_key_derivation_params_0, mut orig_key_derivation_params_1) = key_derivation_params.to_rust(); let mut local_key_derivation_params = (orig_key_derivation_params_0, orig_key_derivation_params_1); - let mut ret = lightning::chain::keysinterface::InMemoryChannelKeys::new(&bitcoin::secp256k1::Secp256k1::new(), funding_key.into_rust(), revocation_base_key.into_rust(), payment_key.into_rust(), delayed_payment_base_key.into_rust(), htlc_base_key.into_rust(), commitment_seed.data, channel_value_satoshis, local_key_derivation_params); +pub extern "C" fn InMemoryChannelKeys_new(mut funding_key: crate::c_types::SecretKey, mut revocation_base_key: crate::c_types::SecretKey, mut payment_key: crate::c_types::SecretKey, mut delayed_payment_base_key: crate::c_types::SecretKey, mut htlc_base_key: crate::c_types::SecretKey, mut commitment_seed: crate::c_types::ThirtyTwoBytes, mut channel_value_satoshis: u64, mut channel_keys_id: crate::c_types::ThirtyTwoBytes) -> crate::chain::keysinterface::InMemoryChannelKeys { + let mut ret = lightning::chain::keysinterface::InMemoryChannelKeys::new(&bitcoin::secp256k1::Secp256k1::new(), funding_key.into_rust(), revocation_base_key.into_rust(), payment_key.into_rust(), delayed_payment_base_key.into_rust(), htlc_base_key.into_rust(), commitment_seed.data, channel_value_satoshis, channel_keys_id.data); crate::chain::keysinterface::InMemoryChannelKeys { inner: Box::into_raw(Box::new(ret)), is_owned: true } } @@ -782,7 +799,7 @@ pub extern "C" fn InMemoryChannelKeys_as_ChannelKeys(this_arg: &InMemoryChannelK pubkeys: crate::ln::chan_utils::ChannelPublicKeys { inner: std::ptr::null_mut(), is_owned: true }, set_pubkeys: Some(InMemoryChannelKeys_ChannelKeys_set_pubkeys), - key_derivation_params: InMemoryChannelKeys_ChannelKeys_key_derivation_params, + channel_keys_id: InMemoryChannelKeys_ChannelKeys_channel_keys_id, sign_counterparty_commitment: InMemoryChannelKeys_ChannelKeys_sign_counterparty_commitment, sign_holder_commitment_and_htlcs: InMemoryChannelKeys_ChannelKeys_sign_holder_commitment_and_htlcs, sign_justice_transaction: InMemoryChannelKeys_ChannelKeys_sign_justice_transaction, @@ -818,10 +835,9 @@ extern "C" fn InMemoryChannelKeys_ChannelKeys_set_pubkeys(trait_self_arg: &Chann } } #[must_use] -extern "C" fn InMemoryChannelKeys_ChannelKeys_key_derivation_params(this_arg: *const c_void) -> crate::c_types::derived::C2Tuple_u64u64Z { - let mut ret = unsafe { &mut *(this_arg as *mut nativeInMemoryChannelKeys) }.key_derivation_params(); - let (mut orig_ret_0, mut orig_ret_1) = ret; let mut local_ret = (orig_ret_0, orig_ret_1).into(); - local_ret +extern "C" fn InMemoryChannelKeys_ChannelKeys_channel_keys_id(this_arg: *const c_void) -> crate::c_types::ThirtyTwoBytes { + let mut ret = unsafe { &mut *(this_arg as *mut nativeInMemoryChannelKeys) }.channel_keys_id(); + crate::c_types::ThirtyTwoBytes { data: ret } } #[must_use] extern "C" fn InMemoryChannelKeys_ChannelKeys_sign_counterparty_commitment(this_arg: *const c_void, commitment_tx: &crate::ln::chan_utils::CommitmentTransaction) -> crate::c_types::derived::CResult_C2Tuple_SignatureCVec_SignatureZZNoneZ { @@ -951,12 +967,12 @@ pub extern "C" fn KeysManager_new(seed: *const [u8; 32], mut network: crate::bit /// Derive an old set of ChannelKeys for per-channel secrets based on a key derivation /// parameters. /// Key derivation parameters are accessible through a per-channel secrets -/// ChannelKeys::key_derivation_params and is provided inside DynamicOuputP2WSH in case of +/// ChannelKeys::channel_keys_id and is provided inside DynamicOuputP2WSH in case of /// onchain output detection for which a corresponding delayed_payment_key must be derived. #[must_use] #[no_mangle] -pub extern "C" fn KeysManager_derive_channel_keys(this_arg: &KeysManager, mut channel_value_satoshis: u64, mut params_1: u64, mut params_2: u64) -> crate::chain::keysinterface::InMemoryChannelKeys { - let mut ret = unsafe { &*this_arg.inner }.derive_channel_keys(channel_value_satoshis, params_1, params_2); +pub extern "C" fn KeysManager_derive_channel_keys(this_arg: &KeysManager, mut channel_value_satoshis: u64, params: *const [u8; 32]) -> crate::chain::keysinterface::InMemoryChannelKeys { + let mut ret = unsafe { &*this_arg.inner }.derive_channel_keys(channel_value_satoshis, unsafe { &*params}); crate::chain::keysinterface::InMemoryChannelKeys { inner: Box::into_raw(Box::new(ret)), is_owned: true } } From 06342a30b15cb8d565343d1803970ce23eeefe31 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 6 Feb 2021 14:06:07 -0500 Subject: [PATCH 5/5] Adapt C++ bindings demo to new API and keys (new funding tx) --- lightning-c-bindings/demo.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lightning-c-bindings/demo.cpp b/lightning-c-bindings/demo.cpp index c19c1e8ec..37bb8d318 100644 --- a/lightning-c-bindings/demo.cpp +++ b/lightning-c-bindings/demo.cpp @@ -61,16 +61,16 @@ const uint8_t channel_open_tx[] = { 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x40, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x20, 0x12, 0x70, 0x44, - 0x41, 0x40, 0xaf, 0xc5, 0x72, 0x97, 0xc8, 0x69, 0xba, 0x04, 0xdb, 0x28, 0x7b, 0xd7, 0x32, 0x07, - 0x33, 0x3a, 0x4a, 0xc2, 0xc5, 0x56, 0x06, 0x05, 0x65, 0xd7, 0xa8, 0xcf, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x40, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0xd1, 0xd9, 0x13, 0xa9, + 0x76, 0x09, 0x05, 0xa3, 0x4d, 0x13, 0x5b, 0x69, 0xaa, 0xe7, 0x79, 0x71, 0xb9, 0x75, 0xa1, 0xd0, + 0x77, 0xcb, 0xa2, 0xf6, 0x6a, 0x25, 0x37, 0x3a, 0xaf, 0xdc, 0x11, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }; // The first transaction in the block is header (80 bytes) + transaction count (1 byte) into the block data. const uint8_t channel_open_txid[] = { - 0x5f, 0xa9, 0x4c, 0xee, 0x7d, 0x4f, 0x4c, 0x75, 0xbb, 0xb8, 0x98, 0xcf, 0xce, 0x5a, 0x84, 0x63, - 0xde, 0x96, 0xa9, 0xbb, 0x34, 0x9a, 0x7a, 0xf9, 0x3f, 0x6a, 0xe0, 0xd4, 0xf8, 0xd2, 0x47, 0xa2 + 0x02, 0xe0, 0x50, 0x05, 0x33, 0xd3, 0x29, 0x66, 0x0c, 0xb2, 0xcb, 0x1e, 0x7a, 0x4a, 0xc7, 0xc7, + 0x8b, 0x02, 0x46, 0x7e, 0x30, 0x2c, 0xe6, 0x19, 0xce, 0x43, 0x3e, 0xdf, 0x43, 0x65, 0xae, 0xf9, }; // Two blocks built on top of channel_open_block: @@ -631,8 +631,7 @@ int main() { // Few extra random tests: LDKSecretKey sk; memset(&sk, 42, 32); - LDKC2Tuple_u64u64Z kdiv_params; - kdiv_params.a = 42; - kdiv_params.b = 42; + LDKThirtyTwoBytes kdiv_params; + memset(&kdiv_params, 43, 32); LDK::InMemoryChannelKeys keys = InMemoryChannelKeys_new(sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params); }