Split out KeysInterface into EntropySource, NodeSigner, and SignerProvider.

This commit is contained in:
Arik Sosman 2022-12-08 15:40:54 -08:00
parent 56afbf5064
commit 9d7bb73b59
No known key found for this signature in database
GPG key ID: F4FB5A3366C4D92E
27 changed files with 393 additions and 286 deletions

View file

@ -36,7 +36,7 @@ use lightning::chain::{BestBlock, ChannelMonitorUpdateStatus, chainmonitor, chan
use lightning::chain::channelmonitor::{ChannelMonitor, MonitorEvent};
use lightning::chain::transaction::OutPoint;
use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
use lightning::chain::keysinterface::{KeyMaterial, KeysInterface, InMemorySigner, Recipient};
use lightning::chain::keysinterface::{KeyMaterial, KeysInterface, InMemorySigner, Recipient, EntropySource, NodeSigner, SignerProvider};
use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
use lightning::ln::channelmanager::{self, ChainParameters, ChannelManager, PaymentSendFailure, ChannelManagerReadArgs, PaymentId};
use lightning::ln::channel::FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
@ -160,13 +160,26 @@ struct KeyProvider {
rand_bytes_id: atomic::AtomicU32,
enforcement_states: Mutex<HashMap<[u8;32], Arc<Mutex<EnforcementState>>>>,
}
impl KeysInterface for KeyProvider {
type Signer = EnforcingSigner;
impl EntropySource for KeyProvider {
fn get_secure_random_bytes(&self) -> [u8; 32] {
let id = self.rand_bytes_id.fetch_add(1, atomic::Ordering::Relaxed);
let mut res = [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, self.node_id];
res[30-4..30].copy_from_slice(&id.to_le_bytes());
res
}
}
impl NodeSigner for KeyProvider {
fn get_node_secret(&self, _recipient: Recipient) -> Result<SecretKey, ()> {
Ok(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, 1, self.node_id]).unwrap())
}
fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
let secp_ctx = Secp256k1::signing_only();
Ok(PublicKey::from_secret_key(&secp_ctx, &self.get_node_secret(recipient)?))
}
fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
let mut node_secret = self.get_node_secret(recipient)?;
if let Some(tweak) = tweak {
@ -179,19 +192,13 @@ impl KeysInterface for KeyProvider {
KeyMaterial([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, 1, self.node_id])
}
fn get_destination_script(&self) -> Script {
let secp_ctx = Secp256k1::signing_only();
let channel_monitor_claim_key = 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, 2, self.node_id]).unwrap();
let our_channel_monitor_claim_key_hash = WPubkeyHash::hash(&PublicKey::from_secret_key(&secp_ctx, &channel_monitor_claim_key).serialize());
Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script()
fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result<RecoverableSignature, ()> {
unreachable!()
}
}
fn get_shutdown_scriptpubkey(&self) -> ShutdownScript {
let secp_ctx = Secp256k1::signing_only();
let secret_key = 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, 3, self.node_id]).unwrap();
let pubkey_hash = WPubkeyHash::hash(&PublicKey::from_secret_key(&secp_ctx, &secret_key).serialize());
ShutdownScript::new_p2wpkh(&pubkey_hash)
}
impl SignerProvider for KeyProvider {
type Signer = EnforcingSigner;
fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32] {
let id = self.rand_bytes_id.fetch_add(1, atomic::Ordering::Relaxed) as u8;
@ -217,13 +224,6 @@ impl KeysInterface for KeyProvider {
EnforcingSigner::new_with_revoked(keys, revoked_commitment, false)
}
fn get_secure_random_bytes(&self) -> [u8; 32] {
let id = self.rand_bytes_id.fetch_add(1, atomic::Ordering::Relaxed);
let mut res = [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, self.node_id];
res[30-4..30].copy_from_slice(&id.to_le_bytes());
res
}
fn read_chan_signer(&self, buffer: &[u8]) -> Result<Self::Signer, DecodeError> {
let mut reader = std::io::Cursor::new(buffer);
@ -237,11 +237,23 @@ impl KeysInterface for KeyProvider {
})
}
fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result<RecoverableSignature, ()> {
unreachable!()
fn get_destination_script(&self) -> Script {
let secp_ctx = Secp256k1::signing_only();
let channel_monitor_claim_key = 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, 2, self.node_id]).unwrap();
let our_channel_monitor_claim_key_hash = WPubkeyHash::hash(&PublicKey::from_secret_key(&secp_ctx, &channel_monitor_claim_key).serialize());
Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script()
}
fn get_shutdown_scriptpubkey(&self) -> ShutdownScript {
let secp_ctx = Secp256k1::signing_only();
let secret_key = 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, 3, self.node_id]).unwrap();
let pubkey_hash = WPubkeyHash::hash(&PublicKey::from_secret_key(&secp_ctx, &secret_key).serialize());
ShutdownScript::new_p2wpkh(&pubkey_hash)
}
}
impl KeysInterface for KeyProvider {}
impl KeyProvider {
fn make_enforcement_state_cell(&self, commitment_seed: [u8; 32]) -> Arc<Mutex<EnforcementState>> {
let mut revoked_commitments = self.enforcement_states.lock().unwrap();

View file

@ -33,7 +33,7 @@ use lightning::chain::{BestBlock, ChannelMonitorUpdateStatus, Confirm, Listen};
use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
use lightning::chain::chainmonitor;
use lightning::chain::transaction::OutPoint;
use lightning::chain::keysinterface::{InMemorySigner, Recipient, KeyMaterial, KeysInterface};
use lightning::chain::keysinterface::{InMemorySigner, Recipient, KeyMaterial, KeysInterface, EntropySource, NodeSigner, SignerProvider};
use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
use lightning::ln::channelmanager::{ChainParameters, ChannelManager, PaymentId};
use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor,IgnoringMessageHandler};
@ -265,13 +265,25 @@ struct KeyProvider {
counter: AtomicU64,
signer_state: RefCell<HashMap<u8, (bool, Arc<Mutex<EnforcementState>>)>>
}
impl KeysInterface for KeyProvider {
type Signer = EnforcingSigner;
impl EntropySource for KeyProvider {
fn get_secure_random_bytes(&self) -> [u8; 32] {
let ctr = self.counter.fetch_add(1, Ordering::Relaxed);
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
(ctr >> 8*7) as u8, (ctr >> 8*6) as u8, (ctr >> 8*5) as u8, (ctr >> 8*4) as u8, (ctr >> 8*3) as u8, (ctr >> 8*2) as u8, (ctr >> 8*1) as u8, 14, (ctr >> 8*0) as u8]
}
}
impl NodeSigner for KeyProvider {
fn get_node_secret(&self, _recipient: Recipient) -> Result<SecretKey, ()> {
Ok(self.node_secret.clone())
}
fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
let secp_ctx = Secp256k1::signing_only();
Ok(PublicKey::from_secret_key(&secp_ctx, &self.get_node_secret(recipient)?))
}
fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
let mut node_secret = self.get_node_secret(recipient)?;
if let Some(tweak) = tweak {
@ -284,19 +296,13 @@ impl KeysInterface for KeyProvider {
self.inbound_payment_key.clone()
}
fn get_destination_script(&self) -> Script {
let secp_ctx = Secp256k1::signing_only();
let channel_monitor_claim_key = SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap();
let our_channel_monitor_claim_key_hash = WPubkeyHash::hash(&PublicKey::from_secret_key(&secp_ctx, &channel_monitor_claim_key).serialize());
Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script()
fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result<RecoverableSignature, ()> {
unreachable!()
}
}
fn get_shutdown_scriptpubkey(&self) -> ShutdownScript {
let secp_ctx = Secp256k1::signing_only();
let secret_key = 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, 0, 1]).unwrap();
let pubkey_hash = WPubkeyHash::hash(&PublicKey::from_secret_key(&secp_ctx, &secret_key).serialize());
ShutdownScript::new_p2wpkh(&pubkey_hash)
}
impl SignerProvider for KeyProvider {
type Signer = EnforcingSigner;
fn generate_channel_keys_id(&self, inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32] {
let ctr = self.counter.fetch_add(1, Ordering::Relaxed) as u8;
@ -337,12 +343,6 @@ impl KeysInterface for KeyProvider {
}, state, false)
}
fn get_secure_random_bytes(&self) -> [u8; 32] {
let ctr = self.counter.fetch_add(1, Ordering::Relaxed);
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
(ctr >> 8*7) as u8, (ctr >> 8*6) as u8, (ctr >> 8*5) as u8, (ctr >> 8*4) as u8, (ctr >> 8*3) as u8, (ctr >> 8*2) as u8, (ctr >> 8*1) as u8, 14, (ctr >> 8*0) as u8]
}
fn read_chan_signer(&self, mut data: &[u8]) -> Result<EnforcingSigner, DecodeError> {
let inner: InMemorySigner = ReadableArgs::read(&mut data, self.node_secret.clone())?;
let state = Arc::new(Mutex::new(EnforcementState::new()));
@ -354,11 +354,23 @@ impl KeysInterface for KeyProvider {
))
}
fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result<RecoverableSignature, ()> {
unreachable!()
fn get_destination_script(&self) -> Script {
let secp_ctx = Secp256k1::signing_only();
let channel_monitor_claim_key = SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap();
let our_channel_monitor_claim_key_hash = WPubkeyHash::hash(&PublicKey::from_secret_key(&secp_ctx, &channel_monitor_claim_key).serialize());
Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script()
}
fn get_shutdown_scriptpubkey(&self) -> ShutdownScript {
let secp_ctx = Secp256k1::signing_only();
let secret_key = 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, 0, 1]).unwrap();
let pubkey_hash = WPubkeyHash::hash(&PublicKey::from_secret_key(&secp_ctx, &secret_key).serialize());
ShutdownScript::new_p2wpkh(&pubkey_hash)
}
}
impl KeysInterface for KeyProvider {}
#[inline]
pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
let input = Arc::new(InputData {

View file

@ -1,11 +1,11 @@
// Imports that need to be added manually
use bitcoin::bech32::u5;
use bitcoin::blockdata::script::Script;
use bitcoin::secp256k1::{PublicKey, Scalar, SecretKey};
use bitcoin::secp256k1::{PublicKey, Scalar, Secp256k1, SecretKey};
use bitcoin::secp256k1::ecdh::SharedSecret;
use bitcoin::secp256k1::ecdsa::RecoverableSignature;
use lightning::chain::keysinterface::{Recipient, KeyMaterial, KeysInterface};
use lightning::chain::keysinterface::{Recipient, KeyMaterial, KeysInterface, EntropySource, NodeSigner, SignerProvider};
use lightning::ln::msgs::{self, DecodeError, OnionMessageHandler};
use lightning::ln::script::ShutdownScript;
use lightning::util::enforcing_trait_impls::EnforcingSigner;
@ -90,13 +90,25 @@ struct KeyProvider {
node_secret: SecretKey,
counter: AtomicU64,
}
impl KeysInterface for KeyProvider {
type Signer = EnforcingSigner;
impl EntropySource for KeyProvider {
fn get_secure_random_bytes(&self) -> [u8; 32] {
let ctr = self.counter.fetch_add(1, Ordering::Relaxed);
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
(ctr >> 8*7) as u8, (ctr >> 8*6) as u8, (ctr >> 8*5) as u8, (ctr >> 8*4) as u8, (ctr >> 8*3) as u8, (ctr >> 8*2) as u8, (ctr >> 8*1) as u8, 14, (ctr >> 8*0) as u8]
}
}
impl NodeSigner for KeyProvider {
fn get_node_secret(&self, _recipient: Recipient) -> Result<SecretKey, ()> {
Ok(self.node_secret.clone())
}
fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
let secp_ctx = Secp256k1::signing_only();
Ok(PublicKey::from_secret_key(&secp_ctx, &self.get_node_secret(recipient)?))
}
fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
let mut node_secret = self.get_node_secret(recipient)?;
if let Some(tweak) = tweak {
@ -107,9 +119,13 @@ impl KeysInterface for KeyProvider {
fn get_inbound_payment_key_material(&self) -> KeyMaterial { unreachable!() }
fn get_destination_script(&self) -> Script { unreachable!() }
fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result<RecoverableSignature, ()> {
unreachable!()
}
}
fn get_shutdown_scriptpubkey(&self) -> ShutdownScript { unreachable!() }
impl SignerProvider for KeyProvider {
type Signer = EnforcingSigner;
fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32] { unreachable!() }
@ -117,19 +133,15 @@ impl KeysInterface for KeyProvider {
unreachable!()
}
fn get_secure_random_bytes(&self) -> [u8; 32] {
let ctr = self.counter.fetch_add(1, Ordering::Relaxed);
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
(ctr >> 8*7) as u8, (ctr >> 8*6) as u8, (ctr >> 8*5) as u8, (ctr >> 8*4) as u8, (ctr >> 8*3) as u8, (ctr >> 8*2) as u8, (ctr >> 8*1) as u8, 14, (ctr >> 8*0) as u8]
}
fn read_chan_signer(&self, _data: &[u8]) -> Result<EnforcingSigner, DecodeError> { unreachable!() }
fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result<RecoverableSignature, ()> {
unreachable!()
}
fn get_destination_script(&self) -> Script { unreachable!() }
fn get_shutdown_scriptpubkey(&self) -> ShutdownScript { unreachable!() }
}
impl KeysInterface for KeyProvider {}
#[cfg(test)]
mod tests {
use lightning::util::logger::{Logger, Record};

View file

@ -17,7 +17,7 @@ extern crate lightning_rapid_gossip_sync;
use lightning::chain;
use lightning::chain::chaininterface::{BroadcasterInterface, FeeEstimator};
use lightning::chain::chainmonitor::{ChainMonitor, Persist};
use lightning::chain::keysinterface::KeysInterface;
use lightning::chain::keysinterface::{KeysInterface, SignerProvider};
use lightning::ln::channelmanager::ChannelManager;
use lightning::ln::msgs::{ChannelMessageHandler, OnionMessageHandler, RoutingMessageHandler};
use lightning::ln::peer_handler::{CustomMessageHandler, PeerManager, SocketDescriptor};
@ -352,7 +352,7 @@ pub async fn process_events_async<
EventHandlerFuture: core::future::Future<Output = ()>,
EventHandler: Fn(Event) -> EventHandlerFuture,
PS: 'static + Deref + Send,
M: 'static + Deref<Target = ChainMonitor<<K::Target as KeysInterface>::Signer, CF, T, F, L, P>> + Send + Sync,
M: 'static + Deref<Target = ChainMonitor<<K::Target as SignerProvider>::Signer, CF, T, F, L, P>> + Send + Sync,
CM: 'static + Deref<Target = ChannelManager<CW, T, K, F, L>> + Send + Sync,
PGS: 'static + Deref<Target = P2PGossipSync<G, CA, L>> + Send + Sync,
RGS: 'static + Deref<Target = RapidGossipSync<G, L>> + Send,
@ -370,12 +370,12 @@ pub async fn process_events_async<
where
CA::Target: 'static + chain::Access,
CF::Target: 'static + chain::Filter,
CW::Target: 'static + chain::Watch<<K::Target as KeysInterface>::Signer>,
CW::Target: 'static + chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: 'static + BroadcasterInterface,
K::Target: 'static + KeysInterface,
F::Target: 'static + FeeEstimator,
L::Target: 'static + Logger,
P::Target: 'static + Persist<<K::Target as KeysInterface>::Signer>,
P::Target: 'static + Persist<<K::Target as SignerProvider>::Signer>,
CMH::Target: 'static + ChannelMessageHandler,
OMH::Target: 'static + OnionMessageHandler,
RMH::Target: 'static + RoutingMessageHandler,
@ -469,7 +469,7 @@ impl BackgroundProcessor {
RMH: 'static + Deref + Send + Sync,
EH: 'static + EventHandler + Send,
PS: 'static + Deref + Send,
M: 'static + Deref<Target = ChainMonitor<<K::Target as KeysInterface>::Signer, CF, T, F, L, P>> + Send + Sync,
M: 'static + Deref<Target = ChainMonitor<<K::Target as SignerProvider>::Signer, CF, T, F, L, P>> + Send + Sync,
CM: 'static + Deref<Target = ChannelManager<CW, T, K, F, L>> + Send + Sync,
PGS: 'static + Deref<Target = P2PGossipSync<G, CA, L>> + Send + Sync,
RGS: 'static + Deref<Target = RapidGossipSync<G, L>> + Send,
@ -484,12 +484,12 @@ impl BackgroundProcessor {
where
CA::Target: 'static + chain::Access,
CF::Target: 'static + chain::Filter,
CW::Target: 'static + chain::Watch<<K::Target as KeysInterface>::Signer>,
CW::Target: 'static + chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: 'static + BroadcasterInterface,
K::Target: 'static + KeysInterface,
F::Target: 'static + FeeEstimator,
L::Target: 'static + Logger,
P::Target: 'static + Persist<<K::Target as KeysInterface>::Signer>,
P::Target: 'static + Persist<<K::Target as SignerProvider>::Signer>,
CMH::Target: 'static + ChannelMessageHandler,
OMH::Target: 'static + OnionMessageHandler,
RMH::Target: 'static + RoutingMessageHandler,
@ -570,7 +570,7 @@ mod tests {
use bitcoin::network::constants::Network;
use lightning::chain::{BestBlock, Confirm, chainmonitor};
use lightning::chain::channelmonitor::ANTI_REORG_DELAY;
use lightning::chain::keysinterface::{InMemorySigner, Recipient, KeysInterface, KeysManager};
use lightning::chain::keysinterface::{InMemorySigner, Recipient, EntropySource, KeysInterface, KeysManager, NodeSigner};
use lightning::chain::transaction::OutPoint;
use lightning::get_event_msg;
use lightning::ln::channelmanager::{self, BREAKDOWN_TIMEOUT, ChainParameters, ChannelManager, SimpleArcChannelManager};

View file

@ -8,7 +8,7 @@ use bech32::ToBase32;
use bitcoin_hashes::Hash;
use lightning::chain;
use lightning::chain::chaininterface::{BroadcasterInterface, FeeEstimator};
use lightning::chain::keysinterface::{Recipient, KeysInterface};
use lightning::chain::keysinterface::{Recipient, KeysInterface, NodeSigner, SignerProvider};
use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
use lightning::ln::channelmanager::{ChannelDetails, ChannelManager, PaymentId, PaymentSendFailure, MIN_FINAL_CLTV_EXPIRY};
#[cfg(feature = "std")]
@ -237,7 +237,7 @@ pub fn create_invoice_from_channelmanager<M: Deref, T: Deref, K: Deref, F: Deref
network: Currency, amt_msat: Option<u64>, description: String, invoice_expiry_delta_secs: u32
) -> Result<Invoice, SignOrCreationError<()>>
where
M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface,
F::Target: FeeEstimator,
@ -268,7 +268,7 @@ pub fn create_invoice_from_channelmanager_with_description_hash<M: Deref, T: Der
invoice_expiry_delta_secs: u32
) -> Result<Invoice, SignOrCreationError<()>>
where
M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface,
F::Target: FeeEstimator,
@ -295,7 +295,7 @@ pub fn create_invoice_from_channelmanager_with_description_hash_and_duration_sin
duration_since_epoch: Duration, invoice_expiry_delta_secs: u32
) -> Result<Invoice, SignOrCreationError<()>>
where
M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface,
F::Target: FeeEstimator,
@ -317,7 +317,7 @@ pub fn create_invoice_from_channelmanager_and_duration_since_epoch<M: Deref, T:
invoice_expiry_delta_secs: u32
) -> Result<Invoice, SignOrCreationError<()>>
where
M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface,
F::Target: FeeEstimator,
@ -338,7 +338,7 @@ fn _create_invoice_from_channelmanager_and_duration_since_epoch<M: Deref, T: Der
duration_since_epoch: Duration, invoice_expiry_delta_secs: u32
) -> Result<Invoice, SignOrCreationError<()>>
where
M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface,
F::Target: FeeEstimator,
@ -363,7 +363,7 @@ pub fn create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_
invoice_expiry_delta_secs: u32, payment_hash: PaymentHash
) -> Result<Invoice, SignOrCreationError<()>>
where
M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface,
F::Target: FeeEstimator,
@ -387,7 +387,7 @@ fn _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_has
invoice_expiry_delta_secs: u32, payment_hash: PaymentHash, payment_secret: PaymentSecret
) -> Result<Invoice, SignOrCreationError<()>>
where
M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface,
F::Target: FeeEstimator,
@ -567,7 +567,7 @@ fn filter_channels<L: Deref>(
impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Payer for ChannelManager<M, T, K, F, L>
where
M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface,
F::Target: FeeEstimator,
@ -613,7 +613,7 @@ mod test {
use crate::{Currency, Description, InvoiceDescription};
use bitcoin_hashes::{Hash, sha256};
use bitcoin_hashes::sha256::Hash as Sha256;
use lightning::chain::keysinterface::PhantomKeysManager;
use lightning::chain::keysinterface::{EntropySource, PhantomKeysManager};
use lightning::ln::{PaymentPreimage, PaymentHash};
use lightning::ln::channelmanager::{self, PhantomRouteHints, MIN_FINAL_CLTV_EXPIRY, PaymentId};
use lightning::ln::functional_test_utils::*;

View file

@ -20,7 +20,7 @@ extern crate libc;
use bitcoin::hash_types::{BlockHash, Txid};
use bitcoin::hashes::hex::FromHex;
use lightning::chain::channelmonitor::ChannelMonitor;
use lightning::chain::keysinterface::KeysInterface;
use lightning::chain::keysinterface::{KeysInterface, SignerProvider};
use lightning::util::ser::{ReadableArgs, Writeable};
use lightning::util::persist::KVStorePersister;
use std::fs;
@ -61,7 +61,7 @@ impl FilesystemPersister {
/// Read `ChannelMonitor`s from disk.
pub fn read_channelmonitors<K: Deref> (
&self, keys_manager: K
) -> Result<Vec<(BlockHash, ChannelMonitor<<K::Target as KeysInterface>::Signer>)>, std::io::Error>
) -> Result<Vec<(BlockHash, ChannelMonitor<<K::Target as SignerProvider>::Signer>)>, std::io::Error>
where K::Target: KeysInterface + Sized,
{
let mut path = PathBuf::from(&self.path_to_channel_data);
@ -105,7 +105,7 @@ impl FilesystemPersister {
let contents = fs::read(&file.path())?;
let mut buffer = Cursor::new(&contents);
match <(BlockHash, ChannelMonitor<<K::Target as KeysInterface>::Signer>)>::read(&mut buffer, &*keys_manager) {
match <(BlockHash, ChannelMonitor<<K::Target as SignerProvider>::Signer>)>::read(&mut buffer, &*keys_manager) {
Ok((blockhash, channel_monitor)) => {
if channel_monitor.get_funding_txo().0.txid != txid.unwrap() || channel_monitor.get_funding_txo().0.index != index.unwrap() {
return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "ChannelMonitor was stored in the wrong file"));

View file

@ -143,8 +143,8 @@ pub enum SpendableOutputDescriptor {
/// 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.
///
/// [`get_shutdown_scriptpubkey`]: KeysInterface::get_shutdown_scriptpubkey
/// [`get_destination_script`]: KeysInterface::get_shutdown_scriptpubkey
/// [`get_shutdown_scriptpubkey`]: SignerProvider::get_shutdown_scriptpubkey
/// [`get_destination_script`]: SignerProvider::get_shutdown_scriptpubkey
StaticOutput {
/// The outpoint which is spendable.
outpoint: OutPoint,
@ -399,7 +399,7 @@ pub trait BaseSign {
///
/// This data is static, and will never change for a channel once set. For a given [`BaseSign`]
/// instance, LDK will call this method exactly once - either immediately after construction
/// (not including if done via [`KeysInterface::read_chan_signer`]) or when the funding
/// (not including if done via [`SignerProvider::read_chan_signer`]) or when the funding
/// information has been generated.
///
/// channel_parameters.is_populated() MUST be true.
@ -417,7 +417,7 @@ pub trait Sign: BaseSign + Writeable {}
/// Specifies the recipient of an invoice.
///
/// This indicates to [`KeysInterface::sign_invoice`] what node secret key should be used to sign
/// This indicates to [`NodeSigner::sign_invoice`] what node secret key should be used to sign
/// the invoice.
pub enum Recipient {
/// The invoice should be signed with the local node secret key.
@ -429,10 +429,15 @@ pub enum Recipient {
PhantomNode,
}
/// A trait to describe an object which can get user secrets and key material.
pub trait KeysInterface {
/// A type which implements [`Sign`] which will be returned by [`Self::derive_channel_signer`].
type Signer : Sign;
/// A trait that describes a source of entropy.
pub trait EntropySource {
/// Gets a unique, cryptographically-secure, random 32-byte value. This method must return a
/// different value each time it is called.
fn get_secure_random_bytes(&self) -> [u8; 32];
}
/// A trait that can handle cryptographic operations at the scope level of a node.
pub trait NodeSigner {
/// Get node secret key based on the provided [`Recipient`].
///
/// The `node_id`/`network_key` is the public key that corresponds to this secret key.
@ -442,6 +447,21 @@ pub trait KeysInterface {
///
/// Errors if the [`Recipient`] variant is not supported by the implementation.
fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()>;
/// Get secret key material as bytes for use in encrypting and decrypting inbound payment data.
///
/// If the implementor of this trait supports [phantom node payments], then every node that is
/// intended to be included in the phantom invoice route hints must return the same value from
/// this method.
// This is because LDK avoids storing inbound payment data by encrypting payment data in the
// payment hash and/or payment secret, therefore for a payment to be receivable by multiple
// nodes, they must share the key that encrypts this payment data.
///
/// This method must return the same value each time it is called.
///
/// [phantom node payments]: PhantomKeysManager
fn get_inbound_payment_key_material(&self) -> KeyMaterial;
/// Get node id based on the provided [`Recipient`]. This public key corresponds to the secret in
/// [`get_node_secret`].
///
@ -451,10 +471,8 @@ pub trait KeysInterface {
/// Errors if the [`Recipient`] variant is not supported by the implementation.
///
/// [`get_node_secret`]: Self::get_node_secret
fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
let secp_ctx = Secp256k1::signing_only();
Ok(PublicKey::from_secret_key(&secp_ctx, &self.get_node_secret(recipient)?))
}
fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()>;
/// Gets the ECDH shared secret of our [`node secret`] and `other_key`, multiplying by `tweak` if
/// one is provided. Note that this tweak can be applied to `other_key` instead of our node
/// secret, though this is less efficient.
@ -463,36 +481,40 @@ pub trait KeysInterface {
///
/// [`node secret`]: Self::get_node_secret
fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()>;
/// Get a script pubkey which we send funds to when claiming on-chain contestable outputs.
/// Sign an invoice.
/// By parameterizing by the raw invoice bytes instead of the hash, we allow implementors of
/// this trait to parse the invoice and make sure they're signing what they expect, rather than
/// blindly signing the hash.
/// The hrp is ascii bytes, while the invoice data is base32.
///
/// 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 a script pubkey which we will send funds to when closing a channel.
/// The secret key used to sign the invoice is dependent on the [`Recipient`].
///
/// 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_scriptpubkey(&self) -> ShutdownScript;
/// Errors if the [`Recipient`] variant is not supported by the implementation.
fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result<RecoverableSignature, ()>;
}
/// A trait that can return signer instances for individual channels.
pub trait SignerProvider {
/// A type which implements [`Sign`] which will be returned by [`Self::derive_channel_signer`].
type Signer : Sign;
/// Generates a unique `channel_keys_id` that can be used to obtain a [`Self::Signer`] through
/// [`KeysInterface::derive_channel_signer`]. The `user_channel_id` is provided to allow
/// implementations of [`KeysInterface`] to maintain a mapping between it and the generated
/// [`SignerProvider::derive_channel_signer`]. The `user_channel_id` is provided to allow
/// implementations of [`SignerProvider`] to maintain a mapping between itself and the generated
/// `channel_keys_id`.
///
/// This method must return a different value each time it is called.
fn generate_channel_keys_id(&self, inbound: bool, channel_value_satoshis: u64, user_channel_id: u128) -> [u8; 32];
/// Derives the private key material backing a `Signer`.
///
/// To derive a new `Signer`, a fresh `channel_keys_id` should be obtained through
/// [`KeysInterface::generate_channel_keys_id`]. Otherwise, an existing `Signer` can be
/// [`SignerProvider::generate_channel_keys_id`]. Otherwise, an existing `Signer` can be
/// re-derived from its `channel_keys_id`, which can be obtained through its trait method
/// [`BaseSign::channel_keys_id`].
fn derive_channel_signer(&self, channel_value_satoshis: u64, channel_keys_id: [u8; 32]) -> Self::Signer;
/// 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 [`Signer`] for this [`KeysInterface`] from the given input stream.
/// This is only called during deserialization of other objects which contain
/// [`Sign`]-implementing objects (i.e., [`ChannelMonitor`]s and [`ChannelManager`]s).
@ -507,31 +529,23 @@ pub trait KeysInterface {
/// [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor
/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
fn read_chan_signer(&self, reader: &[u8]) -> Result<Self::Signer, DecodeError>;
/// Sign an invoice.
/// By parameterizing by the raw invoice bytes instead of the hash, we allow implementors of
/// this trait to parse the invoice and make sure they're signing what they expect, rather than
/// blindly signing the hash.
/// The `hrp` is ASCII bytes, while the invoice data is base32-encoded.
/// Get a script pubkey which we send funds to when claiming on-chain contestable outputs.
///
/// The secret key used to sign the invoice is dependent on the [`Recipient`].
/// 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 a script pubkey which we will send funds to when closing a channel.
///
/// Errors if the [`Recipient`] variant is not supported by the implementation.
fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], receipient: Recipient) -> Result<RecoverableSignature, ()>;
/// Get secret key material as bytes for use in encrypting and decrypting inbound payment data.
///
/// If the implementor of this trait supports [phantom node payments], then every node that is
/// intended to be included in the phantom invoice route hints must return the same value from
/// this method.
// This is because LDK avoids storing inbound payment data by encrypting payment data in the
// payment hash and/or payment secret, therefore for a payment to be receivable by multiple
// nodes, they must share the key that encrypts this payment data.
///
/// This method must return the same value each time it is called.
///
/// [phantom node payments]: PhantomKeysManager
fn get_inbound_payment_key_material(&self) -> KeyMaterial;
/// 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_scriptpubkey(&self) -> ShutdownScript;
}
/// A trait to describe an object which can get user secrets and key material.
pub trait KeysInterface: EntropySource + NodeSigner + SignerProvider {}
#[derive(Clone)]
/// A simple implementation of [`Sign`] that just keeps the private keys in memory.
///
@ -1227,9 +1241,20 @@ impl KeysManager {
}
}
impl KeysInterface for KeysManager {
type Signer = InMemorySigner;
impl EntropySource for KeysManager {
fn get_secure_random_bytes(&self) -> [u8; 32] {
let mut sha = self.rand_bytes_unique_start.clone();
let child_ix = self.rand_bytes_child_index.fetch_add(1, Ordering::AcqRel);
let child_privkey = self.rand_bytes_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32).expect("key space exhausted")).expect("Your RNG is busted");
sha.input(&child_privkey.private_key[..]);
sha.input(b"Unique Secure Random Bytes Salt");
Sha256::from_engine(sha).into_inner()
}
}
impl NodeSigner for KeysManager {
fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
match recipient {
Recipient::Node => Ok(self.node_secret.clone()),
@ -1256,13 +1281,18 @@ impl KeysInterface for KeysManager {
self.inbound_payment_key.clone()
}
fn get_destination_script(&self) -> Script {
self.destination_script.clone()
fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result<RecoverableSignature, ()> {
let preimage = construct_invoice_preimage(&hrp_bytes, &invoice_data);
let secret = match recipient {
Recipient::Node => self.get_node_secret(Recipient::Node)?,
Recipient::PhantomNode => return Err(()),
};
Ok(self.secp_ctx.sign_ecdsa_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &secret))
}
}
fn get_shutdown_scriptpubkey(&self) -> ShutdownScript {
ShutdownScript::new_p2wpkh_from_pubkey(self.shutdown_pubkey.clone())
}
impl SignerProvider for KeysManager {
type Signer = InMemorySigner;
fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, user_channel_id: u128) -> [u8; 32] {
let child_idx = self.channel_child_index.fetch_add(1, Ordering::AcqRel);
@ -1279,31 +1309,21 @@ impl KeysInterface for KeysManager {
self.derive_channel_keys(channel_value_satoshis, &channel_keys_id)
}
fn get_secure_random_bytes(&self) -> [u8; 32] {
let mut sha = self.rand_bytes_unique_start.clone();
let child_ix = self.rand_bytes_child_index.fetch_add(1, Ordering::AcqRel);
let child_privkey = self.rand_bytes_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32).expect("key space exhausted")).expect("Your RNG is busted");
sha.input(&child_privkey.private_key[..]);
sha.input(b"Unique Secure Random Bytes Salt");
Sha256::from_engine(sha).into_inner()
}
fn read_chan_signer(&self, reader: &[u8]) -> Result<Self::Signer, DecodeError> {
InMemorySigner::read(&mut io::Cursor::new(reader), self.node_secret.clone())
}
fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result<RecoverableSignature, ()> {
let preimage = construct_invoice_preimage(&hrp_bytes, &invoice_data);
let secret = match recipient {
Recipient::Node => self.get_node_secret(Recipient::Node)?,
Recipient::PhantomNode => return Err(()),
};
Ok(self.secp_ctx.sign_ecdsa_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &secret))
fn get_destination_script(&self) -> Script {
self.destination_script.clone()
}
fn get_shutdown_scriptpubkey(&self) -> ShutdownScript {
ShutdownScript::new_p2wpkh_from_pubkey(self.shutdown_pubkey.clone())
}
}
impl KeysInterface for KeysManager {}
/// Similar to [`KeysManager`], but allows the node using this struct to receive phantom node
/// payments.
///
@ -1332,9 +1352,13 @@ pub struct PhantomKeysManager {
phantom_node_id: PublicKey,
}
impl KeysInterface for PhantomKeysManager {
type Signer = InMemorySigner;
impl EntropySource for PhantomKeysManager {
fn get_secure_random_bytes(&self) -> [u8; 32] {
self.inner.get_secure_random_bytes()
}
}
impl NodeSigner for PhantomKeysManager {
fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
match recipient {
Recipient::Node => self.inner.get_node_secret(Recipient::Node),
@ -1361,13 +1385,15 @@ impl KeysInterface for PhantomKeysManager {
self.inbound_payment_key.clone()
}
fn get_destination_script(&self) -> Script {
self.inner.get_destination_script()
fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result<RecoverableSignature, ()> {
let preimage = construct_invoice_preimage(&hrp_bytes, &invoice_data);
let secret = self.get_node_secret(recipient)?;
Ok(self.inner.secp_ctx.sign_ecdsa_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &secret))
}
}
fn get_shutdown_scriptpubkey(&self) -> ShutdownScript {
self.inner.get_shutdown_scriptpubkey()
}
impl SignerProvider for PhantomKeysManager {
type Signer = InMemorySigner;
fn generate_channel_keys_id(&self, inbound: bool, channel_value_satoshis: u64, user_channel_id: u128) -> [u8; 32] {
self.inner.generate_channel_keys_id(inbound, channel_value_satoshis, user_channel_id)
@ -1377,21 +1403,21 @@ impl KeysInterface for PhantomKeysManager {
self.inner.derive_channel_signer(channel_value_satoshis, channel_keys_id)
}
fn get_secure_random_bytes(&self) -> [u8; 32] {
self.inner.get_secure_random_bytes()
}
fn read_chan_signer(&self, reader: &[u8]) -> Result<Self::Signer, DecodeError> {
self.inner.read_chan_signer(reader)
}
fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result<RecoverableSignature, ()> {
let preimage = construct_invoice_preimage(&hrp_bytes, &invoice_data);
let secret = self.get_node_secret(recipient)?;
Ok(self.inner.secp_ctx.sign_ecdsa_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &secret))
fn get_destination_script(&self) -> Script {
self.inner.get_destination_script()
}
fn get_shutdown_scriptpubkey(&self) -> ShutdownScript {
self.inner.get_shutdown_scriptpubkey()
}
}
impl KeysInterface for PhantomKeysManager {}
impl PhantomKeysManager {
/// Constructs a [`PhantomKeysManager`] given a 32-byte seed and an additional `cross_node_seed`
/// that is shared across all nodes that intend to participate in [phantom node payments]

View file

@ -1635,7 +1635,7 @@ mod tests {
use crate::ln::chan_utils::{get_htlc_redeemscript, get_to_countersignatory_with_anchors_redeemscript, CommitmentTransaction, TxCreationKeys, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, HTLCOutputInCommitment};
use bitcoin::secp256k1::{PublicKey, SecretKey, Secp256k1};
use crate::util::test_utils;
use crate::chain::keysinterface::{KeysInterface, BaseSign};
use crate::chain::keysinterface::{KeysInterface, BaseSign, SignerProvider};
use bitcoin::{Network, Txid};
use bitcoin::hashes::Hash;
use crate::ln::PaymentHash;

View file

@ -35,7 +35,7 @@ use crate::chain::BestBlock;
use crate::chain::chaininterface::{FeeEstimator, ConfirmationTarget, LowerBoundedFeeEstimator};
use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, LATENCY_GRACE_PERIOD_BLOCKS};
use crate::chain::transaction::{OutPoint, TransactionData};
use crate::chain::keysinterface::{Sign, KeysInterface, BaseSign};
use crate::chain::keysinterface::{Sign, EntropySource, KeysInterface, BaseSign, SignerProvider};
use crate::util::events::ClosureReason;
use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer, VecWriter};
use crate::util::logger::Logger;
@ -740,7 +740,7 @@ pub(super) struct Channel<Signer: Sign> {
channel_ready_event_emitted: bool,
/// The unique identifier used to re-derive the private key material for the channel through
/// [`KeysInterface::derive_channel_signer`].
/// [`SignerProvider::derive_channel_signer`].
channel_keys_id: [u8; 32],
}
@ -2223,7 +2223,7 @@ impl<Signer: Sign> Channel<Signer> {
pub fn funding_created<K: Deref, L: Deref>(
&mut self, msg: &msgs::FundingCreated, best_block: BestBlock, keys_source: &K, logger: &L
) -> Result<(msgs::FundingSigned, ChannelMonitor<<K::Target as KeysInterface>::Signer>, Option<msgs::ChannelReady>), ChannelError>
) -> Result<(msgs::FundingSigned, ChannelMonitor<<K::Target as SignerProvider>::Signer>, Option<msgs::ChannelReady>), ChannelError>
where
K::Target: KeysInterface,
L::Target: Logger
@ -2311,7 +2311,7 @@ impl<Signer: Sign> Channel<Signer> {
/// If this call is successful, broadcast the funding transaction (and not before!)
pub fn funding_signed<K: Deref, L: Deref>(
&mut self, msg: &msgs::FundingSigned, best_block: BestBlock, keys_source: &K, logger: &L
) -> Result<(ChannelMonitor<<K::Target as KeysInterface>::Signer>, Transaction, Option<msgs::ChannelReady>), ChannelError>
) -> Result<(ChannelMonitor<<K::Target as SignerProvider>::Signer>, Transaction, Option<msgs::ChannelReady>), ChannelError>
where
K::Target: KeysInterface,
L::Target: Logger
@ -6329,7 +6329,7 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
}
const MAX_ALLOC_SIZE: usize = 64*1024;
impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<<K::Target as KeysInterface>::Signer>
impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<<K::Target as SignerProvider>::Signer>
where K::Target: KeysInterface {
fn read<R : io::Read>(reader: &mut R, args: (&'a K, u32)) -> Result<Self, DecodeError> {
let (keys_source, serialized_height) = args;
@ -6802,7 +6802,7 @@ mod tests {
use crate::ln::chan_utils::{htlc_success_tx_weight, htlc_timeout_tx_weight};
use crate::chain::BestBlock;
use crate::chain::chaininterface::{FeeEstimator, LowerBoundedFeeEstimator, ConfirmationTarget};
use crate::chain::keysinterface::{BaseSign, InMemorySigner, Recipient, KeyMaterial, KeysInterface};
use crate::chain::keysinterface::{BaseSign, InMemorySigner, Recipient, KeyMaterial, KeysInterface, EntropySource, NodeSigner, SignerProvider};
use crate::chain::transaction::OutPoint;
use crate::util::config::UserConfig;
use crate::util::enforcing_trait_impls::EnforcingSigner;
@ -6851,12 +6851,39 @@ mod tests {
struct Keys {
signer: InMemorySigner,
}
impl KeysInterface for Keys {
impl EntropySource for Keys {
fn get_secure_random_bytes(&self) -> [u8; 32] { [0; 32] }
}
impl NodeSigner for Keys {
fn get_node_secret(&self, _recipient: Recipient) -> Result<SecretKey, ()> { panic!(); }
fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
let secp_ctx = Secp256k1::signing_only();
Ok(PublicKey::from_secret_key(&secp_ctx, &self.get_node_secret(recipient)?))
}
fn ecdh(&self, _recipient: Recipient, _other_key: &PublicKey, _tweak: Option<&Scalar>) -> Result<SharedSecret, ()> { panic!(); }
fn get_inbound_payment_key_material(&self) -> KeyMaterial { panic!(); }
fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result<RecoverableSignature, ()> { panic!(); }
}
impl SignerProvider for Keys {
type Signer = InMemorySigner;
fn get_node_secret(&self, _recipient: Recipient) -> Result<SecretKey, ()> { panic!(); }
fn ecdh(&self, _recipient: Recipient, _other_key: &PublicKey, _tweak: Option<&Scalar>) -> Result<SharedSecret, ()> { panic!(); }
fn get_inbound_payment_key_material(&self) -> KeyMaterial { panic!(); }
fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32] {
self.signer.channel_keys_id()
}
fn derive_channel_signer(&self, _channel_value_satoshis: u64, _channel_keys_id: [u8; 32]) -> Self::Signer {
self.signer.clone()
}
fn read_chan_signer(&self, _data: &[u8]) -> Result<Self::Signer, DecodeError> { panic!(); }
fn get_destination_script(&self) -> Script {
let secp_ctx = Secp256k1::signing_only();
let channel_monitor_claim_key = SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap();
@ -6869,18 +6896,10 @@ mod tests {
let channel_close_key = SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap();
ShutdownScript::new_p2wpkh_from_pubkey(PublicKey::from_secret_key(&secp_ctx, &channel_close_key))
}
fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32] {
self.signer.channel_keys_id()
}
fn derive_channel_signer(&self, _channel_value_satoshis: u64, _channel_keys_id: [u8; 32]) -> Self::Signer {
self.signer.clone()
}
fn get_secure_random_bytes(&self) -> [u8; 32] { [0; 32] }
fn read_chan_signer(&self, _data: &[u8]) -> Result<Self::Signer, DecodeError> { panic!(); }
fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result<RecoverableSignature, ()> { panic!(); }
}
impl KeysInterface for Keys {}
#[cfg(not(feature = "grind_signatures"))]
fn public_from_secret_hex(secp_ctx: &Secp256k1<bitcoin::secp256k1::All>, hex: &str) -> PublicKey {
PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&hex::decode(hex).unwrap()[..]).unwrap())

View file

@ -52,7 +52,7 @@ use crate::ln::onion_utils;
use crate::ln::onion_utils::HTLCFailReason;
use crate::ln::msgs::{ChannelMessageHandler, DecodeError, LightningError, MAX_VALUE_MSAT};
use crate::ln::wire::Encode;
use crate::chain::keysinterface::{Sign, KeysInterface, KeysManager, Recipient};
use crate::chain::keysinterface::{EntropySource, KeysInterface, KeysManager, NodeSigner, Recipient, Sign, SignerProvider};
use crate::util::config::{UserConfig, ChannelConfig};
use crate::util::events::{Event, EventHandler, EventsProvider, MessageSendEvent, MessageSendEventsProvider, ClosureReason, HTLCDestination};
use crate::util::events;
@ -732,7 +732,7 @@ pub type SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, M, T, F, L> = ChannelManage
// | |__`pending_background_events`
//
pub struct ChannelManager<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
where M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
where M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface,
F::Target: FeeEstimator,
@ -753,9 +753,9 @@ pub struct ChannelManager<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
/// See `ChannelManager` struct-level documentation for lock order requirements.
#[cfg(any(test, feature = "_test_utils"))]
pub(super) channel_state: Mutex<ChannelHolder<<K::Target as KeysInterface>::Signer>>,
pub(super) channel_state: Mutex<ChannelHolder<<K::Target as SignerProvider>::Signer>>,
#[cfg(not(any(test, feature = "_test_utils")))]
channel_state: Mutex<ChannelHolder<<K::Target as KeysInterface>::Signer>>,
channel_state: Mutex<ChannelHolder<<K::Target as SignerProvider>::Signer>>,
/// Storage for PaymentSecrets and any requirements on future inbound payments before we will
/// expose them to users via a PaymentClaimable event. HTLCs which do not meet the requirements
@ -1571,7 +1571,7 @@ macro_rules! emit_channel_ready_event {
}
impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F, L>
where M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
where M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface,
F::Target: FeeEstimator,
@ -1739,7 +1739,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
Ok(temporary_channel_id)
}
fn list_channels_with_filter<Fn: FnMut(&(&[u8; 32], &Channel<<K::Target as KeysInterface>::Signer>)) -> bool>(&self, f: Fn) -> Vec<ChannelDetails> {
fn list_channels_with_filter<Fn: FnMut(&(&[u8; 32], &Channel<<K::Target as SignerProvider>::Signer>)) -> bool>(&self, f: Fn) -> Vec<ChannelDetails> {
let mut res = Vec::new();
{
let channel_state = self.channel_state.lock().unwrap();
@ -1823,7 +1823,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
}
/// Helper function that issues the channel close events
fn issue_channel_close_events(&self, channel: &Channel<<K::Target as KeysInterface>::Signer>, closure_reason: ClosureReason) {
fn issue_channel_close_events(&self, channel: &Channel<<K::Target as SignerProvider>::Signer>, closure_reason: ClosureReason) {
let mut pending_events_lock = self.pending_events.lock().unwrap();
match channel.unbroadcasted_funding() {
Some(transaction) => {
@ -2380,7 +2380,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
/// [`MessageSendEvent::BroadcastChannelUpdate`] event.
///
/// May be called with channel_state already locked!
fn get_channel_update_for_broadcast(&self, chan: &Channel<<K::Target as KeysInterface>::Signer>) -> Result<msgs::ChannelUpdate, LightningError> {
fn get_channel_update_for_broadcast(&self, chan: &Channel<<K::Target as SignerProvider>::Signer>) -> Result<msgs::ChannelUpdate, LightningError> {
if !chan.should_announce() {
return Err(LightningError {
err: "Cannot broadcast a channel_update for a private channel".to_owned(),
@ -2399,7 +2399,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
/// and thus MUST NOT be called unless the recipient of the resulting message has already
/// provided evidence that they know about the existence of the channel.
/// May be called with channel_state already locked!
fn get_channel_update_for_unicast(&self, chan: &Channel<<K::Target as KeysInterface>::Signer>) -> Result<msgs::ChannelUpdate, LightningError> {
fn get_channel_update_for_unicast(&self, chan: &Channel<<K::Target as SignerProvider>::Signer>) -> Result<msgs::ChannelUpdate, LightningError> {
log_trace!(self.logger, "Attempting to generate channel update for channel {}", log_bytes!(chan.channel_id()));
let short_channel_id = match chan.get_short_channel_id().or(chan.latest_inbound_scid_alias()) {
None => return Err(LightningError{err: "Channel not yet established".to_owned(), action: msgs::ErrorAction::IgnoreError}),
@ -2408,7 +2408,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
self.get_channel_update_for_onion(short_channel_id, chan)
}
fn get_channel_update_for_onion(&self, short_channel_id: u64, chan: &Channel<<K::Target as KeysInterface>::Signer>) -> Result<msgs::ChannelUpdate, LightningError> {
fn get_channel_update_for_onion(&self, short_channel_id: u64, chan: &Channel<<K::Target as SignerProvider>::Signer>) -> Result<msgs::ChannelUpdate, LightningError> {
log_trace!(self.logger, "Generating channel update for channel {}", log_bytes!(chan.channel_id()));
let were_node_one = PublicKey::from_secret_key(&self.secp_ctx, &self.our_network_key).serialize()[..] < chan.get_counterparty_node_id().serialize()[..];
@ -2894,7 +2894,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
/// Handles the generation of a funding transaction, optionally (for tests) with a function
/// which checks the correctness of the funding transaction given the associated channel.
fn funding_transaction_generated_intern<FundingOutput: Fn(&Channel<<K::Target as KeysInterface>::Signer>, &Transaction) -> Result<OutPoint, APIError>>(
fn funding_transaction_generated_intern<FundingOutput: Fn(&Channel<<K::Target as SignerProvider>::Signer>, &Transaction) -> Result<OutPoint, APIError>>(
&self, temporary_channel_id: &[u8; 32], _counterparty_node_id: &PublicKey, funding_transaction: Transaction, find_funding_output: FundingOutput
) -> Result<(), APIError> {
let (chan, msg) = {
@ -3623,7 +3623,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
self.process_background_events();
}
fn update_channel_fee(&self, chan_id: &[u8; 32], chan: &mut Channel<<K::Target as KeysInterface>::Signer>, new_feerate: u32) -> NotifyOption {
fn update_channel_fee(&self, chan_id: &[u8; 32], chan: &mut Channel<<K::Target as SignerProvider>::Signer>, new_feerate: u32) -> NotifyOption {
if !chan.is_outbound() { return NotifyOption::SkipPersist; }
// If the feerate has decreased by less than half, don't bother
if new_feerate <= chan.get_feerate() && new_feerate * 2 > chan.get_feerate() {
@ -3850,7 +3850,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
///
/// This is for failures on the channel on which the HTLC was *received*, not failures
/// forwarding
fn get_htlc_inbound_temp_fail_err_and_data(&self, desired_err_code: u16, chan: &Channel<<K::Target as KeysInterface>::Signer>) -> (u16, Vec<u8>) {
fn get_htlc_inbound_temp_fail_err_and_data(&self, desired_err_code: u16, chan: &Channel<<K::Target as SignerProvider>::Signer>) -> (u16, Vec<u8>) {
// We can't be sure what SCID was used when relaying inbound towards us, so we have to
// guess somewhat. If its a public channel, we figure best to just use the real SCID (as
// we're not leaking that we have a channel with the counterparty), otherwise we try to use
@ -3870,7 +3870,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
/// Gets an HTLC onion failure code and error data for an `UPDATE` error, given the error code
/// that we want to return and a channel.
fn get_htlc_temp_fail_err_and_data(&self, desired_err_code: u16, scid: u64, chan: &Channel<<K::Target as KeysInterface>::Signer>) -> (u16, Vec<u8>) {
fn get_htlc_temp_fail_err_and_data(&self, desired_err_code: u16, scid: u64, chan: &Channel<<K::Target as SignerProvider>::Signer>) -> (u16, Vec<u8>) {
debug_assert_eq!(desired_err_code & 0x1000, 0x1000);
if let Ok(upd) = self.get_channel_update_for_onion(scid, chan) {
let mut enc = VecWriter(Vec::with_capacity(upd.serialized_length() + 6));
@ -4206,7 +4206,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
}
fn claim_funds_from_hop<ComplFunc: FnOnce(Option<u64>) -> Option<MonitorUpdateCompletionAction>>(&self,
mut channel_state_lock: MutexGuard<ChannelHolder<<K::Target as KeysInterface>::Signer>>,
mut channel_state_lock: MutexGuard<ChannelHolder<<K::Target as SignerProvider>::Signer>>,
prev_hop: HTLCPreviousHopData, payment_preimage: PaymentPreimage, completion_action: ComplFunc)
-> Result<(), (PublicKey, MsgHandleErrInternal)> {
//TODO: Delay the claimed_funds relaying just like we do outbound relay!
@ -4326,7 +4326,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
}
}
fn claim_funds_internal(&self, channel_state_lock: MutexGuard<ChannelHolder<<K::Target as KeysInterface>::Signer>>, source: HTLCSource, payment_preimage: PaymentPreimage, forwarded_htlc_value_msat: Option<u64>, from_onchain: bool, next_channel_id: [u8; 32]) {
fn claim_funds_internal(&self, channel_state_lock: MutexGuard<ChannelHolder<<K::Target as SignerProvider>::Signer>>, source: HTLCSource, payment_preimage: PaymentPreimage, forwarded_htlc_value_msat: Option<u64>, from_onchain: bool, next_channel_id: [u8; 32]) {
match source {
HTLCSource::OutboundRoute { session_priv, payment_id, path, .. } => {
mem::drop(channel_state_lock);
@ -4425,7 +4425,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
/// Handles a channel reentering a functional state, either due to reconnect or a monitor
/// update completion.
fn handle_channel_resumption(&self, pending_msg_events: &mut Vec<MessageSendEvent>,
channel: &mut Channel<<K::Target as KeysInterface>::Signer>, raa: Option<msgs::RevokeAndACK>,
channel: &mut Channel<<K::Target as SignerProvider>::Signer>, raa: Option<msgs::RevokeAndACK>,
commitment_update: Option<msgs::CommitmentUpdate>, order: RAACommitmentOrder,
pending_forwards: Vec<(PendingHTLCInfo, u64)>, funding_broadcastable: Option<Transaction>,
channel_ready: Option<msgs::ChannelReady>, announcement_sigs: Option<msgs::AnnouncementSignatures>)
@ -4968,7 +4968,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.channel_id));
}
let create_pending_htlc_status = |chan: &Channel<<K::Target as KeysInterface>::Signer>, pending_forward_info: PendingHTLCStatus, error_code: u16| {
let create_pending_htlc_status = |chan: &Channel<<K::Target as SignerProvider>::Signer>, pending_forward_info: PendingHTLCStatus, error_code: u16| {
// If the update_add is completely bogus, the call will Err and we will close,
// but if we've sent a shutdown and they haven't acknowledged it yet, we just
// want to reject the new HTLC and fail it backwards instead of forwarding.
@ -5865,7 +5865,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
}
impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> MessageSendEventsProvider for ChannelManager<M, T, K, F, L>
where M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
where M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface,
F::Target: FeeEstimator,
@ -5905,7 +5905,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> MessageSendEventsProvider
impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> EventsProvider for ChannelManager<M, T, K, F, L>
where
M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface,
F::Target: FeeEstimator,
@ -5941,7 +5941,7 @@ where
impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> chain::Listen for ChannelManager<M, T, K, F, L>
where
M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface,
F::Target: FeeEstimator,
@ -5978,7 +5978,7 @@ where
impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> chain::Confirm for ChannelManager<M, T, K, F, L>
where
M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface,
F::Target: FeeEstimator,
@ -6065,7 +6065,7 @@ where
impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F, L>
where
M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface,
F::Target: FeeEstimator,
@ -6074,7 +6074,7 @@ where
/// Calls a function which handles an on-chain event (blocks dis/connected, transactions
/// un/confirmed, etc) on each channel, handling any resulting errors or messages generated by
/// the function.
fn do_chain_event<FN: Fn(&mut Channel<<K::Target as KeysInterface>::Signer>) -> Result<(Option<msgs::ChannelReady>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason>>
fn do_chain_event<FN: Fn(&mut Channel<<K::Target as SignerProvider>::Signer>) -> Result<(Option<msgs::ChannelReady>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason>>
(&self, height_opt: Option<u32>, f: FN) {
// Note that we MUST NOT end up calling methods on self.chain_monitor here - we're called
// during initialization prior to the chain_monitor being fully configured in some cases.
@ -6265,7 +6265,7 @@ where
impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref >
ChannelMessageHandler for ChannelManager<M, T, K, F, L>
where M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
where M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface,
F::Target: FeeEstimator,
@ -6975,7 +6975,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
);
impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable for ChannelManager<M, T, K, F, L>
where M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
where M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface,
F::Target: FeeEstimator,
@ -7172,7 +7172,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable for ChannelMana
///
/// [`ChainMonitor`]: crate::chain::chainmonitor::ChainMonitor
pub struct ChannelManagerReadArgs<'a, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
where M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
where M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface,
F::Target: FeeEstimator,
@ -7217,12 +7217,12 @@ pub struct ChannelManagerReadArgs<'a, M: Deref, T: Deref, K: Deref, F: Deref, L:
/// this struct.
///
/// (C-not exported) because we have no HashMap bindings
pub channel_monitors: HashMap<OutPoint, &'a mut ChannelMonitor<<K::Target as KeysInterface>::Signer>>,
pub channel_monitors: HashMap<OutPoint, &'a mut ChannelMonitor<<K::Target as SignerProvider>::Signer>>,
}
impl<'a, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
ChannelManagerReadArgs<'a, M, T, K, F, L>
where M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
where M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface,
F::Target: FeeEstimator,
@ -7232,7 +7232,7 @@ impl<'a, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
/// HashMap for you. This is primarily useful for C bindings where it is not practical to
/// populate a HashMap directly from C.
pub fn new(keys_manager: K, fee_estimator: F, chain_monitor: M, tx_broadcaster: T, logger: L, default_config: UserConfig,
mut channel_monitors: Vec<&'a mut ChannelMonitor<<K::Target as KeysInterface>::Signer>>) -> Self {
mut channel_monitors: Vec<&'a mut ChannelMonitor<<K::Target as SignerProvider>::Signer>>) -> Self {
Self {
keys_manager, fee_estimator, chain_monitor, tx_broadcaster, logger, default_config,
channel_monitors: channel_monitors.drain(..).map(|monitor| { (monitor.get_funding_txo().0, monitor) }).collect()
@ -7244,7 +7244,7 @@ impl<'a, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
// SipmleArcChannelManager type:
impl<'a, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
ReadableArgs<ChannelManagerReadArgs<'a, M, T, K, F, L>> for (BlockHash, Arc<ChannelManager<M, T, K, F, L>>)
where M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
where M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface,
F::Target: FeeEstimator,
@ -7258,7 +7258,7 @@ impl<'a, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
impl<'a, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
ReadableArgs<ChannelManagerReadArgs<'a, M, T, K, F, L>> for (BlockHash, ChannelManager<M, T, K, F, L>)
where M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
where M::Target: chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: BroadcasterInterface,
K::Target: KeysInterface,
F::Target: FeeEstimator,
@ -7280,7 +7280,7 @@ impl<'a, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
let mut short_to_chan_info = HashMap::with_capacity(cmp::min(channel_count as usize, 128));
let mut channel_closures = Vec::new();
for _ in 0..channel_count {
let mut channel: Channel<<K::Target as KeysInterface>::Signer> = Channel::read(reader, (&args.keys_manager, best_block_height))?;
let mut channel: Channel<<K::Target as SignerProvider>::Signer> = Channel::read(reader, (&args.keys_manager, best_block_height))?;
let funding_txo = channel.get_funding_txo().ok_or(DecodeError::InvalidValue)?;
funding_txo_set.insert(funding_txo.clone());
if let Some(ref mut monitor) = args.channel_monitors.get_mut(&funding_txo) {
@ -7788,7 +7788,7 @@ mod tests {
use crate::util::errors::APIError;
use crate::util::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, ClosureReason};
use crate::util::test_utils;
use crate::chain::keysinterface::KeysInterface;
use crate::chain::keysinterface::{EntropySource, KeysInterface};
#[test]
fn test_notify_limits() {
@ -8354,7 +8354,7 @@ mod tests {
pub mod bench {
use crate::chain::Listen;
use crate::chain::chainmonitor::{ChainMonitor, Persist};
use crate::chain::keysinterface::{KeysManager, KeysInterface, InMemorySigner};
use crate::chain::keysinterface::{EntropySource, KeysManager, KeysInterface, InMemorySigner};
use crate::ln::channelmanager::{self, BestBlock, ChainParameters, ChannelManager, PaymentHash, PaymentPreimage, PaymentId};
use crate::ln::functional_test_utils::*;
use crate::ln::msgs::{ChannelMessageHandler, Init};

View file

@ -10,7 +10,7 @@
//! A bunch of useful utilities for building networks of nodes and exchanging messages between
//! nodes for functional tests.
use crate::chain::{BestBlock, ChannelMonitorUpdateStatus, Confirm, Listen, Watch, keysinterface::KeysInterface};
use crate::chain::{BestBlock, ChannelMonitorUpdateStatus, Confirm, Listen, Watch, keysinterface::EntropySource};
use crate::chain::channelmonitor::ChannelMonitor;
use crate::chain::transaction::OutPoint;
use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
@ -1352,7 +1352,7 @@ macro_rules! get_payment_preimage_hash {
#[macro_export]
macro_rules! get_route {
($send_node: expr, $payment_params: expr, $recv_value: expr, $cltv: expr) => {{
use $crate::chain::keysinterface::KeysInterface;
use $crate::chain::keysinterface::EntropySource;
let scorer = $crate::util::test_utils::TestScorer::with_penalty(0);
let keys_manager = $crate::util::test_utils::TestKeysInterface::new(&[0u8; 32], bitcoin::network::constants::Network::Testnet);
let random_seed_bytes = keys_manager.get_secure_random_bytes();

View file

@ -17,7 +17,7 @@ use crate::chain::chaininterface::LowerBoundedFeeEstimator;
use crate::chain::channelmonitor;
use crate::chain::channelmonitor::{CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY};
use crate::chain::transaction::OutPoint;
use crate::chain::keysinterface::{BaseSign, KeysInterface};
use crate::chain::keysinterface::{BaseSign, EntropySource, KeysInterface};
use crate::ln::{PaymentPreimage, PaymentSecret, PaymentHash};
use crate::ln::channel::{commitment_tx_base_weight, COMMITMENT_TX_WEIGHT_PER_HTLC, CONCURRENT_INBOUND_HTLC_FEE_BUFFER, FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE, MIN_AFFORDABLE_HTLC_COUNT};
use crate::ln::channelmanager::{self, PaymentId, RAACommitmentOrder, PaymentSendFailure, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA};

View file

@ -14,7 +14,7 @@ use bitcoin::hashes::{Hash, HashEngine};
use bitcoin::hashes::cmp::fixed_time_eq;
use bitcoin::hashes::hmac::{Hmac, HmacEngine};
use bitcoin::hashes::sha256::Hash as Sha256;
use crate::chain::keysinterface::{KeyMaterial, KeysInterface};
use crate::chain::keysinterface::{KeyMaterial, KeysInterface, EntropySource};
use crate::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
use crate::ln::msgs;
use crate::ln::msgs::MAX_VALUE_MSAT;
@ -35,9 +35,9 @@ const AMT_MSAT_LEN: usize = 8;
const METHOD_TYPE_OFFSET: usize = 5;
/// A set of keys that were HKDF-expanded from an initial call to
/// [`KeysInterface::get_inbound_payment_key_material`].
/// [`NodeSigner::get_inbound_payment_key_material`].
///
/// [`KeysInterface::get_inbound_payment_key_material`]: crate::chain::keysinterface::KeysInterface::get_inbound_payment_key_material
/// [`NodeSigner::get_inbound_payment_key_material`]: crate::chain::keysinterface::NodeSigner::get_inbound_payment_key_material
pub struct ExpandedKey {
/// The key used to encrypt the bytes containing the payment metadata (i.e. the amount and
/// expiry, included for payment verification on decryption).
@ -84,13 +84,14 @@ impl Method {
/// `ChannelManager` is required. Useful for generating invoices for [phantom node payments] without
/// a `ChannelManager`.
///
/// `keys` is generated by calling [`KeysInterface::get_inbound_payment_key_material`] and then
/// `keys` is generated by calling [`NodeSigner::get_inbound_payment_key_material`] and then
/// calling [`ExpandedKey::new`] with its result. It is recommended to cache this value and not
/// regenerate it for each new inbound payment.
///
/// `current_time` is a Unix timestamp representing the current time.
///
/// [phantom node payments]: crate::chain::keysinterface::PhantomKeysManager
/// [`NodeSigner::get_inbound_payment_key_material`]: crate::chain::keysinterface::NodeSigner::get_inbound_payment_key_material
pub fn create<K: Deref>(keys: &ExpandedKey, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32, keys_manager: &K, current_time: u64) -> Result<(PaymentHash, PaymentSecret), ()>
where K::Target: KeysInterface
{
@ -176,7 +177,7 @@ fn construct_payment_secret(iv_bytes: &[u8; IV_LEN], metadata_bytes: &[u8; METAD
///
/// The metadata is constructed as:
/// payment method (3 bits) || payment amount (8 bytes - 3 bits) || expiry (8 bytes)
/// and encrypted using a key derived from [`KeysInterface::get_inbound_payment_key_material`].
/// and encrypted using a key derived from [`NodeSigner::get_inbound_payment_key_material`].
///
/// Then on payment receipt, we verify in this method that the payment preimage and payment secret
/// match what was constructed.
@ -197,7 +198,7 @@ fn construct_payment_secret(iv_bytes: &[u8; IV_LEN], metadata_bytes: &[u8; METAD
///
/// See [`ExpandedKey`] docs for more info on the individual keys used.
///
/// [`KeysInterface::get_inbound_payment_key_material`]: crate::chain::keysinterface::KeysInterface::get_inbound_payment_key_material
/// [`NodeSigner::get_inbound_payment_key_material`]: crate::chain::keysinterface::NodeSigner::get_inbound_payment_key_material
/// [`create_inbound_payment`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment
/// [`create_inbound_payment_for_hash`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash
pub(super) fn verify<L: Deref>(payment_hash: PaymentHash, payment_data: &msgs::FinalOnionHopData, highest_seen_timestamp: u64, keys: &ExpandedKey, logger: &L) -> Result<Option<PaymentPreimage>, ()>

View file

@ -12,7 +12,7 @@
//! returned errors decode to the correct thing.
use crate::chain::channelmonitor::{CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS};
use crate::chain::keysinterface::{KeysInterface, Recipient};
use crate::chain::keysinterface::{EntropySource, KeysInterface, NodeSigner, Recipient};
use crate::ln::{PaymentHash, PaymentSecret};
use crate::ln::channel::EXPIRE_PREV_CONFIG_TICKS;
use crate::ln::channelmanager::{self, HTLCForwardInfo, CLTV_FAR_FAR_AWAY, MIN_CLTV_EXPIRY_DELTA, PendingAddHTLCInfo, PendingHTLCInfo, PendingHTLCRouting, PaymentId};

View file

@ -14,7 +14,7 @@
use crate::chain::{ChannelMonitorUpdateStatus, Confirm, Listen, Watch};
use crate::chain::channelmonitor::{ANTI_REORG_DELAY, LATENCY_GRACE_PERIOD_BLOCKS};
use crate::chain::transaction::OutPoint;
use crate::chain::keysinterface::KeysInterface;
use crate::chain::keysinterface::{EntropySource, KeysInterface};
use crate::ln::channel::EXPIRE_PREV_CONFIG_TICKS;
use crate::ln::channelmanager::{self, BREAKDOWN_TIMEOUT, ChannelManager, MPP_TIMEOUT_TICKS, MIN_CLTV_EXPIRY_DELTA, PaymentId, PaymentSendFailure, IDEMPOTENCY_TIMEOUT_TICKS};
use crate::ln::msgs;

View file

@ -12,7 +12,7 @@
//! LSP).
use crate::chain::ChannelMonitorUpdateStatus;
use crate::chain::keysinterface::{Recipient, KeysInterface};
use crate::chain::keysinterface::{Recipient, KeysInterface, NodeSigner};
use crate::ln::channelmanager::{self, ChannelManager, MIN_CLTV_EXPIRY_DELTA, PaymentId};
use crate::routing::gossip::RoutingFees;
use crate::routing::router::{PaymentParameters, RouteHint, RouteHintHop};

View file

@ -12,7 +12,7 @@
use crate::chain::{ChannelMonitorUpdateStatus, Watch};
use crate::chain::chaininterface::LowerBoundedFeeEstimator;
use crate::chain::channelmonitor::ChannelMonitor;
use crate::chain::keysinterface::KeysInterface;
use crate::chain::keysinterface::{EntropySource, KeysInterface};
use crate::chain::transaction::OutPoint;
use crate::ln::channelmanager::{self, ChannelManager, ChannelManagerReadArgs, PaymentId};
use crate::ln::msgs;

View file

@ -9,7 +9,7 @@
//! Tests of our shutdown and closing_signed negotiation logic.
use crate::chain::keysinterface::KeysInterface;
use crate::chain::keysinterface::{EntropySource, KeysInterface, SignerProvider};
use crate::chain::transaction::OutPoint;
use crate::ln::channelmanager::{self, PaymentSendFailure, PaymentId};
use crate::routing::router::{PaymentParameters, get_route};

View file

@ -13,7 +13,7 @@ use bitcoin::hashes::{Hash, HashEngine};
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::secp256k1::{self, PublicKey, Scalar, Secp256k1, SecretKey};
use crate::chain::keysinterface::{KeysInterface, Recipient};
use crate::chain::keysinterface::{KeysInterface, NodeSigner, Recipient};
use super::packet::ControlTlvs;
use super::utils;
use crate::ln::msgs::DecodeError;

View file

@ -9,7 +9,7 @@
//! Onion message testing and test utilities live here.
use crate::chain::keysinterface::{KeysInterface, Recipient};
use crate::chain::keysinterface::{KeysInterface, NodeSigner, Recipient};
use crate::ln::features::InitFeatures;
use crate::ln::msgs::{self, DecodeError, OnionMessageHandler};
use super::{BlindedPath, CustomOnionMessageContents, CustomOnionMessageHandler, Destination, OnionMessageContents, OnionMessenger, SendError};

View file

@ -15,7 +15,7 @@ use bitcoin::hashes::hmac::{Hmac, HmacEngine};
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::secp256k1::{self, PublicKey, Scalar, Secp256k1, SecretKey};
use crate::chain::keysinterface::{KeysInterface, KeysManager, Recipient};
use crate::chain::keysinterface::{EntropySource, KeysInterface, KeysManager, NodeSigner, Recipient};
use crate::ln::features::{InitFeatures, NodeFeatures};
use crate::ln::msgs::{self, OnionMessageHandler};
use crate::ln::onion_utils;
@ -160,7 +160,7 @@ pub enum SendError {
GetNodeIdFailed,
/// We attempted to send to a blinded path where we are the introduction node, and failed to
/// advance the blinded path to make the second hop the new introduction node. Either
/// [`KeysInterface::ecdh`] failed, we failed to tweak the current blinding point to get the
/// [`NodeSigner::ecdh`] failed, we failed to tweak the current blinding point to get the
/// new blinding point, or we were attempting to send to ourselves.
BlindedPathAdvanceFailed,
}

View file

@ -2138,7 +2138,7 @@ mod tests {
use crate::routing::scoring::{ChannelUsage, Score, ProbabilisticScorer, ProbabilisticScoringParameters};
use crate::routing::test_utils::{add_channel, add_or_update_node, build_graph, build_line_graph, id_to_feature_flags, get_nodes, update_channel};
use crate::chain::transaction::OutPoint;
use crate::chain::keysinterface::KeysInterface;
use crate::chain::keysinterface::{EntropySource, KeysInterface};
use crate::ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
use crate::ln::msgs::{ErrorAction, LightningError, UnsignedChannelUpdate, MAX_VALUE_MSAT};
use crate::ln::channelmanager;
@ -5652,7 +5652,7 @@ mod benches {
use bitcoin::hashes::Hash;
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
use crate::chain::transaction::OutPoint;
use crate::chain::keysinterface::{KeysManager,KeysInterface};
use crate::chain::keysinterface::{EntropySource, KeysManager,KeysInterface};
use crate::ln::channelmanager::{self, ChannelCounterparty, ChannelDetails};
use crate::ln::features::InvoiceFeatures;
use crate::routing::gossip::NetworkGraph;

View file

@ -120,11 +120,11 @@ pub struct ChannelHandshakeConfig {
/// any attacker who is able to take control of a channel can just as easily send the funds via
/// lightning payments, so we never require that our counterparties support this option.
///
/// The upfront key committed is provided from [`KeysInterface::get_shutdown_scriptpubkey`].
/// The upfront key committed is provided from [`SignerProvider::get_shutdown_scriptpubkey`].
///
/// Default value: true.
///
/// [`KeysInterface::get_shutdown_scriptpubkey`]: crate::chain::keysinterface::KeysInterface::get_shutdown_scriptpubkey
/// [`SignerProvider::get_shutdown_scriptpubkey`]: crate::chain::keysinterface::SignerProvider::get_shutdown_scriptpubkey
pub commit_upfront_shutdown_pubkey: bool,
/// The Proportion of the channel value to configure as counterparty's channel reserve,

View file

@ -55,13 +55,13 @@ pub enum APIError {
/// [`chain::Watch::update_channel`]: crate::chain::Watch::update_channel
/// [`ChannelMonitorUpdateStatus::InProgress`]: crate::chain::ChannelMonitorUpdateStatus::InProgress
MonitorUpdateInProgress,
/// [`KeysInterface::get_shutdown_scriptpubkey`] returned a shutdown scriptpubkey incompatible
/// [`SignerProvider::get_shutdown_scriptpubkey`] returned a shutdown scriptpubkey incompatible
/// with the channel counterparty as negotiated in [`InitFeatures`].
///
/// Using a SegWit v0 script should resolve this issue. If you cannot, you won't be able to open
/// a channel or cooperatively close one with this peer (and will have to force-close instead).
///
/// [`KeysInterface::get_shutdown_scriptpubkey`]: crate::chain::keysinterface::KeysInterface::get_shutdown_scriptpubkey
/// [`SignerProvider::get_shutdown_scriptpubkey`]: crate::chain::keysinterface::SignerProvider::get_shutdown_scriptpubkey
/// [`InitFeatures`]: crate::ln::features::InitFeatures
IncompatibleShutdownScript {
/// The incompatible shutdown script.

View file

@ -16,7 +16,7 @@ use crate::routing::scoring::WriteableScore;
use crate::chain;
use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator};
use crate::chain::chainmonitor::{Persist, MonitorUpdateId};
use crate::chain::keysinterface::{Sign, KeysInterface};
use crate::chain::keysinterface::{Sign, KeysInterface, SignerProvider};
use crate::chain::transaction::OutPoint;
use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate};
use crate::ln::channelmanager::ChannelManager;
@ -34,7 +34,7 @@ pub trait KVStorePersister {
/// Trait that handles persisting a [`ChannelManager`], [`NetworkGraph`], and [`WriteableScore`] to disk.
pub trait Persister<'a, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref, S: WriteableScore<'a>>
where M::Target: 'static + chain::Watch<<K::Target as KeysInterface>::Signer>,
where M::Target: 'static + chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: 'static + BroadcasterInterface,
K::Target: 'static + KeysInterface,
F::Target: 'static + FeeEstimator,
@ -51,7 +51,7 @@ pub trait Persister<'a, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref, S: Wri
}
impl<'a, A: KVStorePersister, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref, S: WriteableScore<'a>> Persister<'a, M, T, K, F, L, S> for A
where M::Target: 'static + chain::Watch<<K::Target as KeysInterface>::Signer>,
where M::Target: 'static + chain::Watch<<K::Target as SignerProvider>::Signer>,
T::Target: 'static + BroadcasterInterface,
K::Target: 'static + KeysInterface,
F::Target: 'static + FeeEstimator,

View file

@ -68,7 +68,7 @@ pub fn scid_from_parts(block: u64, tx_index: u64, vout_index: u64) -> Result<u64
pub(crate) mod fake_scid {
use bitcoin::hash_types::BlockHash;
use bitcoin::hashes::hex::FromHex;
use crate::chain::keysinterface::KeysInterface;
use crate::chain::keysinterface::{KeysInterface, EntropySource};
use crate::util::chacha20::ChaCha20;
use crate::util::scid_utils;

View file

@ -36,7 +36,6 @@ use bitcoin::network::constants::Network;
use bitcoin::hash_types::{BlockHash, Txid};
use bitcoin::secp256k1::{SecretKey, PublicKey, Secp256k1, ecdsa::Signature, Scalar};
use bitcoin::secp256k1::ecdh::SharedSecret;
use bitcoin::secp256k1::ecdsa::RecoverableSignature;
use regex;
@ -48,10 +47,11 @@ use crate::sync::{Mutex, Arc};
use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use core::mem;
use bitcoin::bech32::u5;
use crate::chain::keysinterface::{InMemorySigner, Recipient, KeyMaterial};
use crate::chain::keysinterface::{InMemorySigner, Recipient, KeyMaterial, EntropySource, NodeSigner, SignerProvider};
#[cfg(feature = "std")]
use std::time::{SystemTime, UNIX_EPOCH};
use bitcoin::secp256k1::ecdh::SharedSecret;
use bitcoin::Sequence;
pub struct TestVecWriter(pub Vec<u8>);
@ -72,17 +72,27 @@ impl chaininterface::FeeEstimator for TestFeeEstimator {
}
pub struct OnlyReadsKeysInterface {}
impl keysinterface::KeysInterface for OnlyReadsKeysInterface {
type Signer = EnforcingSigner;
impl EntropySource for OnlyReadsKeysInterface {
fn get_secure_random_bytes(&self) -> [u8; 32] { [0; 32] }}
impl NodeSigner for OnlyReadsKeysInterface {
fn get_node_secret(&self, _recipient: Recipient) -> Result<SecretKey, ()> { unreachable!(); }
fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
let secp_ctx = Secp256k1::signing_only();
Ok(PublicKey::from_secret_key(&secp_ctx, &self.get_node_secret(recipient)?))
}
fn ecdh(&self, _recipient: Recipient, _other_key: &PublicKey, _tweak: Option<&Scalar>) -> Result<SharedSecret, ()> { unreachable!(); }
fn get_inbound_payment_key_material(&self) -> KeyMaterial { unreachable!(); }
fn get_destination_script(&self) -> Script { unreachable!(); }
fn get_shutdown_scriptpubkey(&self) -> ShutdownScript { unreachable!(); }
fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result<RecoverableSignature, ()> { unreachable!(); }
}
impl SignerProvider for OnlyReadsKeysInterface {
type Signer = EnforcingSigner;
fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32] { unreachable!(); }
fn derive_channel_signer(&self, _channel_value_satoshis: u64, _channel_keys_id: [u8; 32]) -> Self::Signer { unreachable!(); }
fn get_secure_random_bytes(&self) -> [u8; 32] { [0; 32] }
fn read_chan_signer(&self, mut reader: &[u8]) -> Result<Self::Signer, msgs::DecodeError> {
let dummy_sk = SecretKey::from_slice(&[42; 32]).unwrap();
@ -95,7 +105,12 @@ impl keysinterface::KeysInterface for OnlyReadsKeysInterface {
false
))
}
fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result<RecoverableSignature, ()> { unreachable!(); }
fn get_destination_script(&self) -> Script { unreachable!(); }
fn get_shutdown_scriptpubkey(&self) -> ShutdownScript { unreachable!(); }
}
impl keysinterface::KeysInterface for OnlyReadsKeysInterface {
}
pub struct TestChainMonitor<'a> {
@ -603,32 +618,40 @@ pub struct TestKeysInterface {
expectations: Mutex<Option<VecDeque<OnGetShutdownScriptpubkey>>>,
}
impl keysinterface::KeysInterface for TestKeysInterface {
type Signer = EnforcingSigner;
impl EntropySource for TestKeysInterface {
fn get_secure_random_bytes(&self) -> [u8; 32] {
let override_random_bytes = self.override_random_bytes.lock().unwrap();
if let Some(bytes) = &*override_random_bytes {
return *bytes;
}
self.backing.get_secure_random_bytes()
}
}
impl NodeSigner for TestKeysInterface {
fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
self.backing.get_node_secret(recipient)
}
fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
self.backing.get_node_id(recipient)
}
fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
self.backing.ecdh(recipient, other_key, tweak)
}
fn get_inbound_payment_key_material(&self) -> keysinterface::KeyMaterial {
self.backing.get_inbound_payment_key_material()
}
fn get_destination_script(&self) -> Script { self.backing.get_destination_script() }
fn get_shutdown_scriptpubkey(&self) -> ShutdownScript {
match &mut *self.expectations.lock().unwrap() {
None => self.backing.get_shutdown_scriptpubkey(),
Some(expectations) => match expectations.pop_front() {
None => panic!("Unexpected get_shutdown_scriptpubkey"),
Some(expectation) => expectation.returns,
},
}
fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result<RecoverableSignature, ()> {
self.backing.sign_invoice(hrp_bytes, invoice_data, recipient)
}
}
impl SignerProvider for TestKeysInterface {
type Signer = EnforcingSigner;
fn generate_channel_keys_id(&self, inbound: bool, channel_value_satoshis: u64, user_channel_id: u128) -> [u8; 32] {
self.backing.generate_channel_keys_id(inbound, channel_value_satoshis, user_channel_id)
@ -640,14 +663,6 @@ impl keysinterface::KeysInterface for TestKeysInterface {
EnforcingSigner::new_with_revoked(keys, state, self.disable_revocation_policy_check)
}
fn get_secure_random_bytes(&self) -> [u8; 32] {
let override_random_bytes = self.override_random_bytes.lock().unwrap();
if let Some(bytes) = &*override_random_bytes {
return *bytes;
}
self.backing.get_secure_random_bytes()
}
fn read_chan_signer(&self, buffer: &[u8]) -> Result<Self::Signer, msgs::DecodeError> {
let mut reader = io::Cursor::new(buffer);
@ -661,11 +676,21 @@ impl keysinterface::KeysInterface for TestKeysInterface {
))
}
fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result<RecoverableSignature, ()> {
self.backing.sign_invoice(hrp_bytes, invoice_data, recipient)
fn get_destination_script(&self) -> Script { self.backing.get_destination_script() }
fn get_shutdown_scriptpubkey(&self) -> ShutdownScript {
match &mut *self.expectations.lock().unwrap() {
None => self.backing.get_shutdown_scriptpubkey(),
Some(expectations) => match expectations.pop_front() {
None => panic!("Unexpected get_shutdown_scriptpubkey"),
Some(expectation) => expectation.returns,
},
}
}
}
impl keysinterface::KeysInterface for TestKeysInterface {}
impl TestKeysInterface {
pub fn new(seed: &[u8; 32], network: Network) -> Self {
let now = Duration::from_secs(genesis_block(network).header.time as u64);
@ -678,7 +703,7 @@ impl TestKeysInterface {
}
}
/// Sets an expectation that [`keysinterface::KeysInterface::get_shutdown_scriptpubkey`] is
/// Sets an expectation that [`keysinterface::SignerProvider::get_shutdown_scriptpubkey`] is
/// called.
pub fn expect(&self, expectation: OnGetShutdownScriptpubkey) -> &Self {
self.expectations.lock().unwrap()
@ -726,7 +751,7 @@ impl Drop for TestKeysInterface {
}
}
/// An expectation that [`keysinterface::KeysInterface::get_shutdown_scriptpubkey`] was called and
/// An expectation that [`keysinterface::SignerProvider::get_shutdown_scriptpubkey`] was called and
/// returns a [`ShutdownScript`].
pub struct OnGetShutdownScriptpubkey {
/// A shutdown script used to close a channel.