mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-02-24 06:57:53 +01:00
Split out KeysInterface into EntropySource, NodeSigner, and SignerProvider.
This commit is contained in:
parent
56afbf5064
commit
9d7bb73b59
27 changed files with 393 additions and 286 deletions
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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::*;
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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>, ()>
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Add table
Reference in a new issue