mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-01-18 21:34:48 +01:00
Merge pull request #1951 from wpaulino/remove-get-node-secret
This commit is contained in:
commit
153b048332
@ -29,6 +29,7 @@ use bitcoin::network::constants::Network;
|
||||
|
||||
use bitcoin::hashes::Hash as TraitImport;
|
||||
use bitcoin::hashes::sha256::Hash as Sha256;
|
||||
use bitcoin::hashes::sha256d::Hash as Sha256dHash;
|
||||
use bitcoin::hash_types::{BlockHash, WPubkeyHash};
|
||||
|
||||
use lightning::chain;
|
||||
@ -54,10 +55,9 @@ use lightning::routing::router::{InFlightHtlcs, Route, RouteHop, RouteParameters
|
||||
use crate::utils::test_logger::{self, Output};
|
||||
use crate::utils::test_persister::TestPersister;
|
||||
|
||||
use bitcoin::secp256k1::{PublicKey, SecretKey, Scalar};
|
||||
use bitcoin::secp256k1::{Message, PublicKey, SecretKey, Scalar, Secp256k1};
|
||||
use bitcoin::secp256k1::ecdh::SharedSecret;
|
||||
use bitcoin::secp256k1::ecdsa::RecoverableSignature;
|
||||
use bitcoin::secp256k1::Secp256k1;
|
||||
use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature};
|
||||
|
||||
use std::mem;
|
||||
use std::cmp::{self, Ordering};
|
||||
@ -174,7 +174,7 @@ impl chain::Watch<EnforcingSigner> for TestChainMonitor {
|
||||
}
|
||||
|
||||
struct KeyProvider {
|
||||
node_id: u8,
|
||||
node_secret: SecretKey,
|
||||
rand_bytes_id: atomic::AtomicU32,
|
||||
enforcement_states: Mutex<HashMap<[u8;32], Arc<Mutex<EnforcementState>>>>,
|
||||
}
|
||||
@ -182,37 +182,45 @@ struct KeyProvider {
|
||||
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];
|
||||
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_secret[31]];
|
||||
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)?))
|
||||
let node_secret = match recipient {
|
||||
Recipient::Node => Ok(&self.node_secret),
|
||||
Recipient::PhantomNode => Err(())
|
||||
}?;
|
||||
Ok(PublicKey::from_secret_key(&Secp256k1::signing_only(), node_secret))
|
||||
}
|
||||
|
||||
fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
|
||||
let mut node_secret = self.get_node_secret(recipient)?;
|
||||
let mut node_secret = match recipient {
|
||||
Recipient::Node => Ok(self.node_secret.clone()),
|
||||
Recipient::PhantomNode => Err(())
|
||||
}?;
|
||||
if let Some(tweak) = tweak {
|
||||
node_secret = node_secret.mul_tweak(tweak).unwrap();
|
||||
node_secret = node_secret.mul_tweak(tweak).map_err(|_| ())?;
|
||||
}
|
||||
Ok(SharedSecret::new(other_key, &node_secret))
|
||||
}
|
||||
|
||||
fn get_inbound_payment_key_material(&self) -> KeyMaterial {
|
||||
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])
|
||||
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_secret[31]])
|
||||
}
|
||||
|
||||
fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result<RecoverableSignature, ()> {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn sign_gossip_message(&self, msg: lightning::ln::msgs::UnsignedGossipMessage) -> Result<Signature, ()> {
|
||||
let msg_hash = Message::from_slice(&Sha256dHash::hash(&msg.encode()[..])[..]).map_err(|_| ())?;
|
||||
let secp_ctx = Secp256k1::signing_only();
|
||||
Ok(secp_ctx.sign_ecdsa(&msg_hash, &self.node_secret))
|
||||
}
|
||||
}
|
||||
|
||||
impl SignerProvider for KeyProvider {
|
||||
@ -228,13 +236,12 @@ impl SignerProvider for KeyProvider {
|
||||
let id = channel_keys_id[0];
|
||||
let keys = InMemorySigner::new(
|
||||
&secp_ctx,
|
||||
self.get_node_secret(Recipient::Node).unwrap(),
|
||||
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, 4, self.node_id]).unwrap(),
|
||||
SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, self.node_id]).unwrap(),
|
||||
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, 6, self.node_id]).unwrap(),
|
||||
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, 7, self.node_id]).unwrap(),
|
||||
SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, self.node_id]).unwrap(),
|
||||
[id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, self.node_id],
|
||||
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, 4, self.node_secret[31]]).unwrap(),
|
||||
SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, self.node_secret[31]]).unwrap(),
|
||||
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, 6, self.node_secret[31]]).unwrap(),
|
||||
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, 7, self.node_secret[31]]).unwrap(),
|
||||
SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, self.node_secret[31]]).unwrap(),
|
||||
[id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, self.node_secret[31]],
|
||||
channel_value_satoshis,
|
||||
channel_keys_id,
|
||||
);
|
||||
@ -245,7 +252,7 @@ impl SignerProvider for KeyProvider {
|
||||
fn read_chan_signer(&self, buffer: &[u8]) -> Result<Self::Signer, DecodeError> {
|
||||
let mut reader = std::io::Cursor::new(buffer);
|
||||
|
||||
let inner: InMemorySigner = ReadableArgs::read(&mut reader, self.get_node_secret(Recipient::Node).unwrap())?;
|
||||
let inner: InMemorySigner = Readable::read(&mut reader)?;
|
||||
let state = self.make_enforcement_state_cell(inner.commitment_seed);
|
||||
|
||||
Ok(EnforcingSigner {
|
||||
@ -257,14 +264,14 @@ impl SignerProvider for KeyProvider {
|
||||
|
||||
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 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_secret[31]]).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 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_secret[31]]).unwrap();
|
||||
let pubkey_hash = WPubkeyHash::hash(&PublicKey::from_secret_key(&secp_ctx, &secret_key).serialize());
|
||||
ShutdownScript::new_p2wpkh(&pubkey_hash)
|
||||
}
|
||||
@ -402,7 +409,8 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
|
||||
macro_rules! make_node {
|
||||
($node_id: expr, $fee_estimator: expr) => { {
|
||||
let logger: Arc<dyn Logger> = Arc::new(test_logger::TestLogger::new($node_id.to_string(), out.clone()));
|
||||
let keys_manager = Arc::new(KeyProvider { node_id: $node_id, rand_bytes_id: atomic::AtomicU32::new(0), enforcement_states: Mutex::new(HashMap::new()) });
|
||||
let node_secret = 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, $node_id]).unwrap();
|
||||
let keys_manager = Arc::new(KeyProvider { node_secret, rand_bytes_id: atomic::AtomicU32::new(0), enforcement_states: Mutex::new(HashMap::new()) });
|
||||
let monitor = Arc::new(TestChainMonitor::new(broadcast.clone(), logger.clone(), $fee_estimator.clone(),
|
||||
Arc::new(TestPersister {
|
||||
update_ret: Mutex::new(ChannelMonitorUpdateStatus::Completed)
|
||||
|
@ -26,6 +26,7 @@ use bitcoin::network::constants::Network;
|
||||
use bitcoin::hashes::Hash as TraitImport;
|
||||
use bitcoin::hashes::HashEngine as TraitImportEngine;
|
||||
use bitcoin::hashes::sha256::Hash as Sha256;
|
||||
use bitcoin::hashes::sha256d::Hash as Sha256dHash;
|
||||
use bitcoin::hash_types::{Txid, BlockHash, WPubkeyHash};
|
||||
|
||||
use lightning::chain;
|
||||
@ -47,15 +48,14 @@ use lightning::util::errors::APIError;
|
||||
use lightning::util::events::Event;
|
||||
use lightning::util::enforcing_trait_impls::{EnforcingSigner, EnforcementState};
|
||||
use lightning::util::logger::Logger;
|
||||
use lightning::util::ser::ReadableArgs;
|
||||
use lightning::util::ser::{Readable, Writeable};
|
||||
|
||||
use crate::utils::test_logger;
|
||||
use crate::utils::test_persister::TestPersister;
|
||||
|
||||
use bitcoin::secp256k1::{PublicKey, SecretKey, Scalar};
|
||||
use bitcoin::secp256k1::{Message, PublicKey, SecretKey, Scalar, Secp256k1};
|
||||
use bitcoin::secp256k1::ecdh::SharedSecret;
|
||||
use bitcoin::secp256k1::ecdsa::RecoverableSignature;
|
||||
use bitcoin::secp256k1::Secp256k1;
|
||||
use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature};
|
||||
|
||||
use std::cell::RefCell;
|
||||
use hashbrown::{HashMap, hash_map};
|
||||
@ -183,7 +183,7 @@ impl<'a> std::hash::Hash for Peer<'a> {
|
||||
type ChannelMan<'a> = ChannelManager<
|
||||
Arc<chainmonitor::ChainMonitor<EnforcingSigner, Arc<dyn chain::Filter>, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<TestPersister>>>,
|
||||
Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<KeyProvider>, Arc<KeyProvider>, Arc<FuzzEstimator>, &'a FuzzRouter, Arc<dyn Logger>>;
|
||||
type PeerMan<'a> = PeerManager<Peer<'a>, Arc<ChannelMan<'a>>, Arc<P2PGossipSync<Arc<NetworkGraph<Arc<dyn Logger>>>, Arc<dyn chain::Access>, Arc<dyn Logger>>>, IgnoringMessageHandler, Arc<dyn Logger>, IgnoringMessageHandler>;
|
||||
type PeerMan<'a> = PeerManager<Peer<'a>, Arc<ChannelMan<'a>>, Arc<P2PGossipSync<Arc<NetworkGraph<Arc<dyn Logger>>>, Arc<dyn chain::Access>, Arc<dyn Logger>>>, IgnoringMessageHandler, Arc<dyn Logger>, IgnoringMessageHandler, Arc<KeyProvider>>;
|
||||
|
||||
struct MoneyLossDetector<'a> {
|
||||
manager: Arc<ChannelMan<'a>>,
|
||||
@ -293,19 +293,21 @@ impl EntropySource for KeyProvider {
|
||||
}
|
||||
|
||||
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)?))
|
||||
let node_secret = match recipient {
|
||||
Recipient::Node => Ok(&self.node_secret),
|
||||
Recipient::PhantomNode => Err(())
|
||||
}?;
|
||||
Ok(PublicKey::from_secret_key(&Secp256k1::signing_only(), node_secret))
|
||||
}
|
||||
|
||||
fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
|
||||
let mut node_secret = self.get_node_secret(recipient)?;
|
||||
let mut node_secret = match recipient {
|
||||
Recipient::Node => Ok(self.node_secret.clone()),
|
||||
Recipient::PhantomNode => Err(())
|
||||
}?;
|
||||
if let Some(tweak) = tweak {
|
||||
node_secret = node_secret.mul_tweak(tweak).unwrap();
|
||||
node_secret = node_secret.mul_tweak(tweak).map_err(|_| ())?;
|
||||
}
|
||||
Ok(SharedSecret::new(other_key, &node_secret))
|
||||
}
|
||||
@ -317,6 +319,12 @@ impl NodeSigner for KeyProvider {
|
||||
fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result<RecoverableSignature, ()> {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn sign_gossip_message(&self, msg: lightning::ln::msgs::UnsignedGossipMessage) -> Result<Signature, ()> {
|
||||
let msg_hash = Message::from_slice(&Sha256dHash::hash(&msg.encode()[..])[..]).map_err(|_| ())?;
|
||||
let secp_ctx = Secp256k1::signing_only();
|
||||
Ok(secp_ctx.sign_ecdsa(&msg_hash, &self.node_secret))
|
||||
}
|
||||
}
|
||||
|
||||
impl SignerProvider for KeyProvider {
|
||||
@ -335,7 +343,6 @@ impl SignerProvider for KeyProvider {
|
||||
EnforcingSigner::new_with_revoked(if inbound {
|
||||
InMemorySigner::new(
|
||||
&secp_ctx,
|
||||
self.node_secret.clone(),
|
||||
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, ctr]).unwrap(),
|
||||
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, ctr]).unwrap(),
|
||||
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, ctr]).unwrap(),
|
||||
@ -348,7 +355,6 @@ impl SignerProvider for KeyProvider {
|
||||
} else {
|
||||
InMemorySigner::new(
|
||||
&secp_ctx,
|
||||
self.node_secret.clone(),
|
||||
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, 7, ctr]).unwrap(),
|
||||
SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, ctr]).unwrap(),
|
||||
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, 9, ctr]).unwrap(),
|
||||
@ -362,7 +368,7 @@ impl SignerProvider for KeyProvider {
|
||||
}
|
||||
|
||||
fn read_chan_signer(&self, mut data: &[u8]) -> Result<EnforcingSigner, DecodeError> {
|
||||
let inner: InMemorySigner = ReadableArgs::read(&mut data, self.node_secret.clone())?;
|
||||
let inner: InMemorySigner = Readable::read(&mut data)?;
|
||||
let state = Arc::new(Mutex::new(EnforcementState::new()));
|
||||
|
||||
Ok(EnforcingSigner::new_with_revoked(
|
||||
@ -446,7 +452,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
|
||||
// keys subsequently generated in this test. Rather than regenerating all the messages manually,
|
||||
// it's easier to just increment the counter here so the keys don't change.
|
||||
keys_manager.counter.fetch_sub(3, Ordering::AcqRel);
|
||||
let our_id = PublicKey::from_secret_key(&Secp256k1::signing_only(), &keys_manager.get_node_secret(Recipient::Node).unwrap());
|
||||
let our_id = &keys_manager.get_node_id(Recipient::Node).unwrap();
|
||||
let network_graph = Arc::new(NetworkGraph::new(genesis_block(network).block_hash(), Arc::clone(&logger)));
|
||||
let gossip_sync = Arc::new(P2PGossipSync::new(Arc::clone(&network_graph), None, Arc::clone(&logger)));
|
||||
let scorer = FixedPenaltyScorer::with_penalty(0);
|
||||
@ -456,7 +462,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
|
||||
chan_handler: channelmanager.clone(),
|
||||
route_handler: gossip_sync.clone(),
|
||||
onion_message_handler: IgnoringMessageHandler {},
|
||||
}, our_network_key, 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, 15, 0], Arc::clone(&logger), IgnoringMessageHandler{}));
|
||||
}, 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, 15, 0], Arc::clone(&logger), IgnoringMessageHandler{}, keys_manager.clone()));
|
||||
|
||||
let mut should_forward = false;
|
||||
let mut payments_received: Vec<PaymentHash> = Vec::new();
|
||||
|
@ -100,17 +100,19 @@ impl EntropySource for KeyProvider {
|
||||
}
|
||||
|
||||
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)?))
|
||||
let node_secret = match recipient {
|
||||
Recipient::Node => Ok(&self.node_secret),
|
||||
Recipient::PhantomNode => Err(())
|
||||
}?;
|
||||
Ok(PublicKey::from_secret_key(&Secp256k1::signing_only(), node_secret))
|
||||
}
|
||||
|
||||
fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
|
||||
let mut node_secret = self.get_node_secret(recipient)?;
|
||||
let mut node_secret = match recipient {
|
||||
Recipient::Node => Ok(self.node_secret.clone()),
|
||||
Recipient::PhantomNode => Err(())
|
||||
}?;
|
||||
if let Some(tweak) = tweak {
|
||||
node_secret = node_secret.mul_tweak(tweak).map_err(|_| ())?;
|
||||
}
|
||||
@ -122,6 +124,10 @@ impl NodeSigner for KeyProvider {
|
||||
fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result<RecoverableSignature, ()> {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn sign_gossip_message(&self, _msg: lightning::ln::msgs::UnsignedGossipMessage) -> Result<bitcoin::secp256k1::ecdsa::Signature, ()> {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
impl SignerProvider for KeyProvider {
|
||||
|
@ -8,6 +8,7 @@
|
||||
// licenses.
|
||||
|
||||
use lightning::ln::peer_channel_encryptor::PeerChannelEncryptor;
|
||||
use lightning::util::test_utils::TestNodeSigner;
|
||||
|
||||
use bitcoin::secp256k1::{Secp256k1, PublicKey, SecretKey};
|
||||
|
||||
@ -41,6 +42,7 @@ pub fn do_test(data: &[u8]) {
|
||||
Ok(key) => key,
|
||||
Err(_) => return,
|
||||
};
|
||||
let node_signer = TestNodeSigner::new(our_network_key);
|
||||
let ephemeral_key = match SecretKey::from_slice(get_slice!(32)) {
|
||||
Ok(key) => key,
|
||||
Err(_) => return,
|
||||
@ -53,15 +55,15 @@ pub fn do_test(data: &[u8]) {
|
||||
};
|
||||
let mut crypter = PeerChannelEncryptor::new_outbound(their_pubkey, ephemeral_key);
|
||||
crypter.get_act_one(&secp_ctx);
|
||||
match crypter.process_act_two(get_slice!(50), &our_network_key, &secp_ctx) {
|
||||
match crypter.process_act_two(get_slice!(50), &&node_signer) {
|
||||
Ok(_) => {},
|
||||
Err(_) => return,
|
||||
}
|
||||
assert!(crypter.is_ready_for_encryption());
|
||||
crypter
|
||||
} else {
|
||||
let mut crypter = PeerChannelEncryptor::new_inbound(&our_network_key, &secp_ctx);
|
||||
match crypter.process_act_one_with_keys(get_slice!(50), &our_network_key, ephemeral_key, &secp_ctx) {
|
||||
let mut crypter = PeerChannelEncryptor::new_inbound(&&node_signer);
|
||||
match crypter.process_act_one_with_keys(get_slice!(50), &&node_signer, ephemeral_key, &secp_ctx) {
|
||||
Ok(_) => {},
|
||||
Err(_) => return,
|
||||
}
|
||||
|
@ -385,7 +385,7 @@ pub async fn process_events_async<
|
||||
PGS: 'static + Deref<Target = P2PGossipSync<G, CA, L>> + Send + Sync,
|
||||
RGS: 'static + Deref<Target = RapidGossipSync<G, L>> + Send,
|
||||
UMH: 'static + Deref + Send + Sync,
|
||||
PM: 'static + Deref<Target = PeerManager<Descriptor, CMH, RMH, OMH, L, UMH>> + Send + Sync,
|
||||
PM: 'static + Deref<Target = PeerManager<Descriptor, CMH, RMH, OMH, L, UMH, NS>> + Send + Sync,
|
||||
S: 'static + Deref<Target = SC> + Send + Sync,
|
||||
SC: WriteableScore<'a>,
|
||||
SleepFuture: core::future::Future<Output = bool> + core::marker::Unpin,
|
||||
@ -514,7 +514,7 @@ impl BackgroundProcessor {
|
||||
PGS: 'static + Deref<Target = P2PGossipSync<G, CA, L>> + Send + Sync,
|
||||
RGS: 'static + Deref<Target = RapidGossipSync<G, L>> + Send,
|
||||
UMH: 'static + Deref + Send + Sync,
|
||||
PM: 'static + Deref<Target = PeerManager<Descriptor, CMH, RMH, OMH, L, UMH>> + Send + Sync,
|
||||
PM: 'static + Deref<Target = PeerManager<Descriptor, CMH, RMH, OMH, L, UMH, NS>> + Send + Sync,
|
||||
S: 'static + Deref<Target = SC> + Send + Sync,
|
||||
SC: WriteableScore<'a>,
|
||||
>(
|
||||
@ -615,7 +615,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, EntropySource, KeysManager, NodeSigner};
|
||||
use lightning::chain::keysinterface::{InMemorySigner, EntropySource, KeysManager};
|
||||
use lightning::chain::transaction::OutPoint;
|
||||
use lightning::get_event_msg;
|
||||
use lightning::ln::channelmanager::{BREAKDOWN_TIMEOUT, ChainParameters, ChannelManager, SimpleArcChannelManager};
|
||||
@ -663,7 +663,7 @@ mod tests {
|
||||
node: Arc<SimpleArcChannelManager<ChainMonitor, test_utils::TestBroadcaster, test_utils::TestFeeEstimator, test_utils::TestLogger>>,
|
||||
p2p_gossip_sync: PGS,
|
||||
rapid_gossip_sync: RGS,
|
||||
peer_manager: Arc<PeerManager<TestDescriptor, Arc<test_utils::TestChannelMessageHandler>, Arc<test_utils::TestRoutingMessageHandler>, IgnoringMessageHandler, Arc<test_utils::TestLogger>, IgnoringMessageHandler>>,
|
||||
peer_manager: Arc<PeerManager<TestDescriptor, Arc<test_utils::TestChannelMessageHandler>, Arc<test_utils::TestRoutingMessageHandler>, IgnoringMessageHandler, Arc<test_utils::TestLogger>, IgnoringMessageHandler, Arc<KeysManager>>>,
|
||||
chain_monitor: Arc<ChainMonitor>,
|
||||
persister: Arc<FilesystemPersister>,
|
||||
tx_broadcaster: Arc<test_utils::TestBroadcaster>,
|
||||
@ -786,7 +786,7 @@ mod tests {
|
||||
let p2p_gossip_sync = Arc::new(P2PGossipSync::new(network_graph.clone(), Some(chain_source.clone()), logger.clone()));
|
||||
let rapid_gossip_sync = Arc::new(RapidGossipSync::new(network_graph.clone()));
|
||||
let msg_handler = MessageHandler { chan_handler: Arc::new(test_utils::TestChannelMessageHandler::new()), route_handler: Arc::new(test_utils::TestRoutingMessageHandler::new()), onion_message_handler: IgnoringMessageHandler{}};
|
||||
let peer_manager = Arc::new(PeerManager::new(msg_handler, keys_manager.get_node_secret(Recipient::Node).unwrap(), 0, &seed, logger.clone(), IgnoringMessageHandler{}));
|
||||
let peer_manager = Arc::new(PeerManager::new(msg_handler, 0, &seed, logger.clone(), IgnoringMessageHandler{}, keys_manager.clone()));
|
||||
let node = Node { node: manager, p2p_gossip_sync, rapid_gossip_sync, peer_manager, chain_monitor, persister, tx_broadcaster, network_graph, logger, best_block, scorer };
|
||||
nodes.push(node);
|
||||
}
|
||||
|
@ -32,6 +32,7 @@
|
||||
//! type TxBroadcaster = dyn lightning::chain::chaininterface::BroadcasterInterface + Send + Sync;
|
||||
//! type FeeEstimator = dyn lightning::chain::chaininterface::FeeEstimator + Send + Sync;
|
||||
//! type Logger = dyn lightning::util::logger::Logger + Send + Sync;
|
||||
//! type NodeSigner = dyn lightning::chain::keysinterface::NodeSigner + Send + Sync;
|
||||
//! type ChainAccess = dyn lightning::chain::Access + Send + Sync;
|
||||
//! type ChainFilter = dyn lightning::chain::Filter + Send + Sync;
|
||||
//! type DataPersister = dyn lightning::chain::chainmonitor::Persist<lightning::chain::keysinterface::InMemorySigner> + Send + Sync;
|
||||
@ -80,6 +81,7 @@ use tokio::{io, time};
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::io::{AsyncReadExt, AsyncWrite, AsyncWriteExt};
|
||||
|
||||
use lightning::chain::keysinterface::NodeSigner;
|
||||
use lightning::ln::peer_handler;
|
||||
use lightning::ln::peer_handler::SocketDescriptor as LnSocketTrait;
|
||||
use lightning::ln::peer_handler::CustomMessageHandler;
|
||||
@ -123,21 +125,23 @@ struct Connection {
|
||||
id: u64,
|
||||
}
|
||||
impl Connection {
|
||||
async fn poll_event_process<PM, CMH, RMH, OMH, L, UMH>(
|
||||
async fn poll_event_process<PM, CMH, RMH, OMH, L, UMH, NS>(
|
||||
peer_manager: PM,
|
||||
mut event_receiver: mpsc::Receiver<()>,
|
||||
) where
|
||||
PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH>> + 'static + Send + Sync,
|
||||
PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH, NS>> + 'static + Send + Sync,
|
||||
CMH: Deref + 'static + Send + Sync,
|
||||
RMH: Deref + 'static + Send + Sync,
|
||||
OMH: Deref + 'static + Send + Sync,
|
||||
L: Deref + 'static + Send + Sync,
|
||||
UMH: Deref + 'static + Send + Sync,
|
||||
NS: Deref + 'static + Send + Sync,
|
||||
CMH::Target: ChannelMessageHandler + Send + Sync,
|
||||
RMH::Target: RoutingMessageHandler + Send + Sync,
|
||||
OMH::Target: OnionMessageHandler + Send + Sync,
|
||||
L::Target: Logger + Send + Sync,
|
||||
UMH::Target: CustomMessageHandler + Send + Sync,
|
||||
NS::Target: NodeSigner + Send + Sync,
|
||||
{
|
||||
loop {
|
||||
if event_receiver.recv().await.is_none() {
|
||||
@ -147,24 +151,26 @@ impl Connection {
|
||||
}
|
||||
}
|
||||
|
||||
async fn schedule_read<PM, CMH, RMH, OMH, L, UMH>(
|
||||
async fn schedule_read<PM, CMH, RMH, OMH, L, UMH, NS>(
|
||||
peer_manager: PM,
|
||||
us: Arc<Mutex<Self>>,
|
||||
mut reader: io::ReadHalf<TcpStream>,
|
||||
mut read_wake_receiver: mpsc::Receiver<()>,
|
||||
mut write_avail_receiver: mpsc::Receiver<()>,
|
||||
) where
|
||||
PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH>> + 'static + Send + Sync + Clone,
|
||||
PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH, NS>> + 'static + Send + Sync + Clone,
|
||||
CMH: Deref + 'static + Send + Sync,
|
||||
RMH: Deref + 'static + Send + Sync,
|
||||
OMH: Deref + 'static + Send + Sync,
|
||||
L: Deref + 'static + Send + Sync,
|
||||
UMH: Deref + 'static + Send + Sync,
|
||||
NS: Deref + 'static + Send + Sync,
|
||||
CMH::Target: ChannelMessageHandler + 'static + Send + Sync,
|
||||
RMH::Target: RoutingMessageHandler + 'static + Send + Sync,
|
||||
OMH::Target: OnionMessageHandler + 'static + Send + Sync,
|
||||
L::Target: Logger + 'static + Send + Sync,
|
||||
UMH::Target: CustomMessageHandler + 'static + Send + Sync,
|
||||
NS::Target: NodeSigner + 'static + Send + Sync,
|
||||
{
|
||||
// Create a waker to wake up poll_event_process, above
|
||||
let (event_waker, event_receiver) = mpsc::channel(1);
|
||||
@ -283,21 +289,23 @@ fn get_addr_from_stream(stream: &StdTcpStream) -> Option<NetAddress> {
|
||||
/// The returned future will complete when the peer is disconnected and associated handling
|
||||
/// futures are freed, though, because all processing futures are spawned with tokio::spawn, you do
|
||||
/// not need to poll the provided future in order to make progress.
|
||||
pub fn setup_inbound<PM, CMH, RMH, OMH, L, UMH>(
|
||||
pub fn setup_inbound<PM, CMH, RMH, OMH, L, UMH, NS>(
|
||||
peer_manager: PM,
|
||||
stream: StdTcpStream,
|
||||
) -> impl std::future::Future<Output=()> where
|
||||
PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH>> + 'static + Send + Sync + Clone,
|
||||
PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH, NS>> + 'static + Send + Sync + Clone,
|
||||
CMH: Deref + 'static + Send + Sync,
|
||||
RMH: Deref + 'static + Send + Sync,
|
||||
OMH: Deref + 'static + Send + Sync,
|
||||
L: Deref + 'static + Send + Sync,
|
||||
UMH: Deref + 'static + Send + Sync,
|
||||
NS: Deref + 'static + Send + Sync,
|
||||
CMH::Target: ChannelMessageHandler + Send + Sync,
|
||||
RMH::Target: RoutingMessageHandler + Send + Sync,
|
||||
OMH::Target: OnionMessageHandler + Send + Sync,
|
||||
L::Target: Logger + Send + Sync,
|
||||
UMH::Target: CustomMessageHandler + Send + Sync,
|
||||
NS::Target: NodeSigner + Send + Sync,
|
||||
{
|
||||
let remote_addr = get_addr_from_stream(&stream);
|
||||
let (reader, write_receiver, read_receiver, us) = Connection::new(stream);
|
||||
@ -336,22 +344,24 @@ pub fn setup_inbound<PM, CMH, RMH, OMH, L, UMH>(
|
||||
/// The returned future will complete when the peer is disconnected and associated handling
|
||||
/// futures are freed, though, because all processing futures are spawned with tokio::spawn, you do
|
||||
/// not need to poll the provided future in order to make progress.
|
||||
pub fn setup_outbound<PM, CMH, RMH, OMH, L, UMH>(
|
||||
pub fn setup_outbound<PM, CMH, RMH, OMH, L, UMH, NS>(
|
||||
peer_manager: PM,
|
||||
their_node_id: PublicKey,
|
||||
stream: StdTcpStream,
|
||||
) -> impl std::future::Future<Output=()> where
|
||||
PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH>> + 'static + Send + Sync + Clone,
|
||||
PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH, NS>> + 'static + Send + Sync + Clone,
|
||||
CMH: Deref + 'static + Send + Sync,
|
||||
RMH: Deref + 'static + Send + Sync,
|
||||
OMH: Deref + 'static + Send + Sync,
|
||||
L: Deref + 'static + Send + Sync,
|
||||
UMH: Deref + 'static + Send + Sync,
|
||||
NS: Deref + 'static + Send + Sync,
|
||||
CMH::Target: ChannelMessageHandler + Send + Sync,
|
||||
RMH::Target: RoutingMessageHandler + Send + Sync,
|
||||
OMH::Target: OnionMessageHandler + Send + Sync,
|
||||
L::Target: Logger + Send + Sync,
|
||||
UMH::Target: CustomMessageHandler + Send + Sync,
|
||||
NS::Target: NodeSigner + Send + Sync,
|
||||
{
|
||||
let remote_addr = get_addr_from_stream(&stream);
|
||||
let (reader, mut write_receiver, read_receiver, us) = Connection::new(stream);
|
||||
@ -419,22 +429,24 @@ pub fn setup_outbound<PM, CMH, RMH, OMH, L, UMH>(
|
||||
/// disconnected and associated handling futures are freed, though, because all processing in said
|
||||
/// futures are spawned with tokio::spawn, you do not need to poll the second future in order to
|
||||
/// make progress.
|
||||
pub async fn connect_outbound<PM, CMH, RMH, OMH, L, UMH>(
|
||||
pub async fn connect_outbound<PM, CMH, RMH, OMH, L, UMH, NS>(
|
||||
peer_manager: PM,
|
||||
their_node_id: PublicKey,
|
||||
addr: SocketAddr,
|
||||
) -> Option<impl std::future::Future<Output=()>> where
|
||||
PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH>> + 'static + Send + Sync + Clone,
|
||||
PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH, NS>> + 'static + Send + Sync + Clone,
|
||||
CMH: Deref + 'static + Send + Sync,
|
||||
RMH: Deref + 'static + Send + Sync,
|
||||
OMH: Deref + 'static + Send + Sync,
|
||||
L: Deref + 'static + Send + Sync,
|
||||
UMH: Deref + 'static + Send + Sync,
|
||||
NS: Deref + 'static + Send + Sync,
|
||||
CMH::Target: ChannelMessageHandler + Send + Sync,
|
||||
RMH::Target: RoutingMessageHandler + Send + Sync,
|
||||
OMH::Target: OnionMessageHandler + Send + Sync,
|
||||
L::Target: Logger + Send + Sync,
|
||||
UMH::Target: CustomMessageHandler + Send + Sync,
|
||||
NS::Target: NodeSigner + Send + Sync,
|
||||
{
|
||||
if let Ok(Ok(stream)) = time::timeout(Duration::from_secs(10), async { TcpStream::connect(&addr).await.map(|s| s.into_std().unwrap()) }).await {
|
||||
Some(setup_outbound(peer_manager, their_node_id, stream))
|
||||
@ -573,6 +585,7 @@ mod tests {
|
||||
use lightning::ln::peer_handler::{MessageHandler, PeerManager};
|
||||
use lightning::ln::features::NodeFeatures;
|
||||
use lightning::util::events::*;
|
||||
use lightning::util::test_utils::TestNodeSigner;
|
||||
use bitcoin::secp256k1::{Secp256k1, SecretKey, PublicKey};
|
||||
|
||||
use tokio::sync::mpsc;
|
||||
@ -688,7 +701,7 @@ mod tests {
|
||||
chan_handler: Arc::clone(&a_handler),
|
||||
route_handler: Arc::clone(&a_handler),
|
||||
onion_message_handler: Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}),
|
||||
}, a_key.clone(), 0, &[1; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{})));
|
||||
}, 0, &[1; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}), Arc::new(TestNodeSigner::new(a_key))));
|
||||
|
||||
let (b_connected_sender, mut b_connected) = mpsc::channel(1);
|
||||
let (b_disconnected_sender, mut b_disconnected) = mpsc::channel(1);
|
||||
@ -703,7 +716,7 @@ mod tests {
|
||||
chan_handler: Arc::clone(&b_handler),
|
||||
route_handler: Arc::clone(&b_handler),
|
||||
onion_message_handler: Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}),
|
||||
}, b_key.clone(), 0, &[2; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{})));
|
||||
}, 0, &[2; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}), Arc::new(TestNodeSigner::new(b_key))));
|
||||
|
||||
// We bind on localhost, hoping the environment is properly configured with a local
|
||||
// address. This may not always be the case in containers and the like, so if this test is
|
||||
@ -756,7 +769,7 @@ mod tests {
|
||||
chan_handler: Arc::new(lightning::ln::peer_handler::ErroringMessageHandler::new()),
|
||||
onion_message_handler: Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}),
|
||||
route_handler: Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}),
|
||||
}, a_key, 0, &[1; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{})));
|
||||
}, 0, &[1; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}), Arc::new(TestNodeSigner::new(a_key))));
|
||||
|
||||
// Make two connections, one for an inbound and one for an outbound connection
|
||||
let conn_a = {
|
||||
|
@ -4185,7 +4185,6 @@ mod tests {
|
||||
SecretKey::from_slice(&[41; 32]).unwrap(),
|
||||
SecretKey::from_slice(&[41; 32]).unwrap(),
|
||||
SecretKey::from_slice(&[41; 32]).unwrap(),
|
||||
SecretKey::from_slice(&[41; 32]).unwrap(),
|
||||
[41; 32],
|
||||
0,
|
||||
[0; 32],
|
||||
|
@ -34,14 +34,14 @@ use bitcoin::{PackedLockTime, secp256k1, Sequence, Witness};
|
||||
|
||||
use crate::util::transaction_utils;
|
||||
use crate::util::crypto::{hkdf_extract_expand_twice, sign};
|
||||
use crate::util::ser::{Writeable, Writer, Readable, ReadableArgs};
|
||||
use crate::util::ser::{Writeable, Writer, Readable};
|
||||
#[cfg(anchors)]
|
||||
use crate::util::events::HTLCDescriptor;
|
||||
use crate::chain::transaction::OutPoint;
|
||||
use crate::ln::channel::ANCHOR_OUTPUT_VALUE_SATOSHI;
|
||||
use crate::ln::{chan_utils, PaymentPreimage};
|
||||
use crate::ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, HolderCommitmentTransaction, ChannelTransactionParameters, CommitmentTransaction, ClosingTransaction};
|
||||
use crate::ln::msgs::UnsignedChannelAnnouncement;
|
||||
use crate::ln::msgs::{UnsignedChannelAnnouncement, UnsignedGossipMessage};
|
||||
use crate::ln::script::ShutdownScript;
|
||||
|
||||
use crate::prelude::*;
|
||||
@ -383,17 +383,18 @@ pub trait BaseSign {
|
||||
fn sign_holder_anchor_input(
|
||||
&self, anchor_tx: &Transaction, input: usize, secp_ctx: &Secp256k1<secp256k1::All>,
|
||||
) -> Result<Signature, ()>;
|
||||
/// Signs a channel announcement message with our funding key and our node secret key (aka
|
||||
/// node_id or network_key), proving it comes from one of the channel participants.
|
||||
/// Signs a channel announcement message with our funding key proving it comes from one of the
|
||||
/// channel participants.
|
||||
///
|
||||
/// The first returned signature should be from our node secret key, the second from our
|
||||
/// funding key.
|
||||
/// Channel announcements also require a signature from each node's network key. Our node
|
||||
/// signature is computed through [`NodeSigner::sign_gossip_message`].
|
||||
///
|
||||
/// Note that if this fails or is rejected, the channel will not be publicly announced and
|
||||
/// our counterparty may (though likely will not) close the channel on us for violating the
|
||||
/// protocol.
|
||||
fn sign_channel_announcement(&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>)
|
||||
-> Result<(Signature, Signature), ()>;
|
||||
fn sign_channel_announcement_with_funding_key(
|
||||
&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>
|
||||
) -> Result<Signature, ()>;
|
||||
/// Set the counterparty static channel data, including basepoints,
|
||||
/// `counterparty_selected`/`holder_selected_contest_delay` and funding outpoint.
|
||||
///
|
||||
@ -438,16 +439,6 @@ pub trait EntropySource {
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// This method must return the same value each time it is called with a given [`Recipient`]
|
||||
/// parameter.
|
||||
///
|
||||
/// 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
|
||||
@ -462,24 +453,22 @@ pub trait NodeSigner {
|
||||
/// [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`].
|
||||
/// Get node id based on the provided [`Recipient`].
|
||||
///
|
||||
/// This method must return the same value each time it is called with a given [`Recipient`]
|
||||
/// parameter.
|
||||
///
|
||||
/// 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, ()>;
|
||||
|
||||
/// Gets the ECDH shared secret of our [`node secret`] and `other_key`, multiplying by `tweak` if
|
||||
/// 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.
|
||||
///
|
||||
/// Errors if the [`Recipient`] variant is not supported by the implementation.
|
||||
/// Note that if this fails while attempting to forward an HTLC, LDK will panic. The error
|
||||
/// should be resolved to allow LDK to resume forwarding HTLCs.
|
||||
///
|
||||
/// [`node secret`]: Self::get_node_secret
|
||||
/// Errors if the [`Recipient`] variant is not supported by the implementation.
|
||||
fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()>;
|
||||
|
||||
/// Sign an invoice.
|
||||
@ -494,6 +483,14 @@ pub trait NodeSigner {
|
||||
///
|
||||
/// 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, ()>;
|
||||
|
||||
/// Sign a gossip message.
|
||||
///
|
||||
/// Note that if this fails, LDK may panic and the message will not be broadcast to the network
|
||||
/// or a possible channel counterparty. If LDK panics, the error should be resolved to allow the
|
||||
/// message to be broadcast, as otherwise it may prevent one from receiving funds over the
|
||||
/// corresponding channel.
|
||||
fn sign_gossip_message(&self, msg: UnsignedGossipMessage) -> Result<Signature, ()>;
|
||||
}
|
||||
|
||||
/// A trait that can return signer instances for individual channels.
|
||||
@ -566,8 +563,6 @@ pub struct InMemorySigner {
|
||||
pub commitment_seed: [u8; 32],
|
||||
/// Holder public keys and basepoints.
|
||||
pub(crate) holder_channel_pubkeys: ChannelPublicKeys,
|
||||
/// Private key of our node secret, used for signing channel announcements.
|
||||
node_secret: SecretKey,
|
||||
/// Counterparty public keys and counterparty/holder `selected_contest_delay`, populated on channel acceptance.
|
||||
channel_parameters: Option<ChannelTransactionParameters>,
|
||||
/// The total value of this channel.
|
||||
@ -580,7 +575,6 @@ impl InMemorySigner {
|
||||
/// Creates a new [`InMemorySigner`].
|
||||
pub fn new<C: Signing>(
|
||||
secp_ctx: &Secp256k1<C>,
|
||||
node_secret: SecretKey,
|
||||
funding_key: SecretKey,
|
||||
revocation_base_key: SecretKey,
|
||||
payment_key: SecretKey,
|
||||
@ -601,7 +595,6 @@ impl InMemorySigner {
|
||||
delayed_payment_base_key,
|
||||
htlc_base_key,
|
||||
commitment_seed,
|
||||
node_secret,
|
||||
channel_value_satoshis,
|
||||
holder_channel_pubkeys,
|
||||
channel_parameters: None,
|
||||
@ -872,10 +865,11 @@ impl BaseSign for InMemorySigner {
|
||||
Ok(sign(secp_ctx, &hash_to_message!(&sighash[..]), &self.funding_key))
|
||||
}
|
||||
|
||||
fn sign_channel_announcement(&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>)
|
||||
-> Result<(Signature, Signature), ()> {
|
||||
fn sign_channel_announcement_with_funding_key(
|
||||
&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>
|
||||
) -> Result<Signature, ()> {
|
||||
let msghash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]);
|
||||
Ok((sign(secp_ctx, &msghash, &self.node_secret), sign(secp_ctx, &msghash, &self.funding_key)))
|
||||
Ok(sign(secp_ctx, &msghash, &self.funding_key))
|
||||
}
|
||||
|
||||
fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters) {
|
||||
@ -915,8 +909,8 @@ impl Writeable for InMemorySigner {
|
||||
}
|
||||
}
|
||||
|
||||
impl ReadableArgs<SecretKey> for InMemorySigner {
|
||||
fn read<R: io::Read>(reader: &mut R, node_secret: SecretKey) -> Result<Self, DecodeError> {
|
||||
impl Readable for InMemorySigner {
|
||||
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
|
||||
let _ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
|
||||
|
||||
let funding_key = Readable::read(reader)?;
|
||||
@ -941,7 +935,6 @@ impl ReadableArgs<SecretKey> for InMemorySigner {
|
||||
payment_key,
|
||||
delayed_payment_base_key,
|
||||
htlc_base_key,
|
||||
node_secret,
|
||||
commitment_seed,
|
||||
channel_value_satoshis,
|
||||
holder_channel_pubkeys,
|
||||
@ -1099,7 +1092,6 @@ impl KeysManager {
|
||||
|
||||
InMemorySigner::new(
|
||||
&self.secp_ctx,
|
||||
self.node_secret,
|
||||
funding_key,
|
||||
revocation_base_key,
|
||||
payment_key,
|
||||
@ -1256,13 +1248,6 @@ impl EntropySource for KeysManager {
|
||||
}
|
||||
|
||||
impl NodeSigner for KeysManager {
|
||||
fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
|
||||
match recipient {
|
||||
Recipient::Node => Ok(self.node_secret.clone()),
|
||||
Recipient::PhantomNode => Err(())
|
||||
}
|
||||
}
|
||||
|
||||
fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
|
||||
match recipient {
|
||||
Recipient::Node => Ok(self.node_id.clone()),
|
||||
@ -1271,7 +1256,10 @@ impl NodeSigner for KeysManager {
|
||||
}
|
||||
|
||||
fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
|
||||
let mut node_secret = self.get_node_secret(recipient)?;
|
||||
let mut node_secret = match recipient {
|
||||
Recipient::Node => Ok(self.node_secret.clone()),
|
||||
Recipient::PhantomNode => Err(())
|
||||
}?;
|
||||
if let Some(tweak) = tweak {
|
||||
node_secret = node_secret.mul_tweak(tweak).map_err(|_| ())?;
|
||||
}
|
||||
@ -1285,10 +1273,15 @@ impl NodeSigner for KeysManager {
|
||||
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))
|
||||
Recipient::Node => Ok(&self.node_secret),
|
||||
Recipient::PhantomNode => Err(())
|
||||
}?;
|
||||
Ok(self.secp_ctx.sign_ecdsa_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), secret))
|
||||
}
|
||||
|
||||
fn sign_gossip_message(&self, msg: UnsignedGossipMessage) -> Result<Signature, ()> {
|
||||
let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]);
|
||||
Ok(sign(&self.secp_ctx, &msg_hash, &self.node_secret))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1316,7 +1309,7 @@ impl SignerProvider for KeysManager {
|
||||
}
|
||||
|
||||
fn read_chan_signer(&self, reader: &[u8]) -> Result<Self::Signer, DecodeError> {
|
||||
InMemorySigner::read(&mut io::Cursor::new(reader), self.node_secret.clone())
|
||||
InMemorySigner::read(&mut io::Cursor::new(reader))
|
||||
}
|
||||
|
||||
fn get_destination_script(&self) -> Script {
|
||||
@ -1363,13 +1356,6 @@ impl EntropySource for PhantomKeysManager {
|
||||
}
|
||||
|
||||
impl NodeSigner for PhantomKeysManager {
|
||||
fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
|
||||
match recipient {
|
||||
Recipient::Node => self.inner.get_node_secret(Recipient::Node),
|
||||
Recipient::PhantomNode => Ok(self.phantom_secret.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
|
||||
match recipient {
|
||||
Recipient::Node => self.inner.get_node_id(Recipient::Node),
|
||||
@ -1378,7 +1364,10 @@ impl NodeSigner for PhantomKeysManager {
|
||||
}
|
||||
|
||||
fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
|
||||
let mut node_secret = self.get_node_secret(recipient)?;
|
||||
let mut node_secret = match recipient {
|
||||
Recipient::Node => self.inner.node_secret.clone(),
|
||||
Recipient::PhantomNode => self.phantom_secret.clone(),
|
||||
};
|
||||
if let Some(tweak) = tweak {
|
||||
node_secret = node_secret.mul_tweak(tweak).map_err(|_| ())?;
|
||||
}
|
||||
@ -1391,8 +1380,15 @@ impl NodeSigner for PhantomKeysManager {
|
||||
|
||||
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))
|
||||
let secret = match recipient {
|
||||
Recipient::Node => &self.inner.node_secret,
|
||||
Recipient::PhantomNode => &self.phantom_secret,
|
||||
};
|
||||
Ok(self.inner.secp_ctx.sign_ecdsa_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), secret))
|
||||
}
|
||||
|
||||
fn sign_gossip_message(&self, msg: UnsignedGossipMessage) -> Result<Signature, ()> {
|
||||
self.inner.sign_gossip_message(msg)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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, EntropySource, BaseSign, SignerProvider};
|
||||
use crate::chain::keysinterface::{Sign, EntropySource, BaseSign, NodeSigner, Recipient, SignerProvider};
|
||||
use crate::util::events::ClosureReason;
|
||||
use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer, VecWriter};
|
||||
use crate::util::logger::Logger;
|
||||
@ -2427,7 +2427,14 @@ impl<Signer: Sign> Channel<Signer> {
|
||||
/// Handles a channel_ready message from our peer. If we've already sent our channel_ready
|
||||
/// and the channel is now usable (and public), this may generate an announcement_signatures to
|
||||
/// reply with.
|
||||
pub fn channel_ready<L: Deref>(&mut self, msg: &msgs::ChannelReady, node_pk: PublicKey, genesis_block_hash: BlockHash, user_config: &UserConfig, best_block: &BestBlock, logger: &L) -> Result<Option<msgs::AnnouncementSignatures>, ChannelError> where L::Target: Logger {
|
||||
pub fn channel_ready<NS: Deref, L: Deref>(
|
||||
&mut self, msg: &msgs::ChannelReady, node_signer: &NS, genesis_block_hash: BlockHash,
|
||||
user_config: &UserConfig, best_block: &BestBlock, logger: &L
|
||||
) -> Result<Option<msgs::AnnouncementSignatures>, ChannelError>
|
||||
where
|
||||
NS::Target: NodeSigner,
|
||||
L::Target: Logger
|
||||
{
|
||||
if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 {
|
||||
self.workaround_lnd_bug_4006 = Some(msg.clone());
|
||||
return Err(ChannelError::Ignore("Peer sent channel_ready when we needed a channel_reestablish. The peer is likely lnd, see https://github.com/lightningnetwork/lnd/issues/4006".to_owned()));
|
||||
@ -2481,7 +2488,7 @@ impl<Signer: Sign> Channel<Signer> {
|
||||
|
||||
log_info!(logger, "Received channel_ready from peer for channel {}", log_bytes!(self.channel_id()));
|
||||
|
||||
Ok(self.get_announcement_sigs(node_pk, genesis_block_hash, user_config, best_block.height(), logger))
|
||||
Ok(self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, best_block.height(), logger))
|
||||
}
|
||||
|
||||
/// Returns transaction if there is pending funding transaction that is yet to broadcast
|
||||
@ -3785,7 +3792,14 @@ impl<Signer: Sign> Channel<Signer> {
|
||||
/// Indicates that the latest ChannelMonitor update has been committed by the client
|
||||
/// successfully and we should restore normal operation. Returns messages which should be sent
|
||||
/// to the remote side.
|
||||
pub fn monitor_updating_restored<L: Deref>(&mut self, logger: &L, node_pk: PublicKey, genesis_block_hash: BlockHash, user_config: &UserConfig, best_block_height: u32) -> MonitorRestoreUpdates where L::Target: Logger {
|
||||
pub fn monitor_updating_restored<L: Deref, NS: Deref>(
|
||||
&mut self, logger: &L, node_signer: &NS, genesis_block_hash: BlockHash,
|
||||
user_config: &UserConfig, best_block_height: u32
|
||||
) -> MonitorRestoreUpdates
|
||||
where
|
||||
L::Target: Logger,
|
||||
NS::Target: NodeSigner
|
||||
{
|
||||
assert_eq!(self.channel_state & ChannelState::MonitorUpdateInProgress as u32, ChannelState::MonitorUpdateInProgress as u32);
|
||||
self.channel_state &= !(ChannelState::MonitorUpdateInProgress as u32);
|
||||
|
||||
@ -3820,7 +3834,7 @@ impl<Signer: Sign> Channel<Signer> {
|
||||
})
|
||||
} else { None };
|
||||
|
||||
let announcement_sigs = self.get_announcement_sigs(node_pk, genesis_block_hash, user_config, best_block_height, logger);
|
||||
let announcement_sigs = self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, best_block_height, logger);
|
||||
|
||||
let mut accepted_htlcs = Vec::new();
|
||||
mem::swap(&mut accepted_htlcs, &mut self.monitor_pending_forwards);
|
||||
@ -3972,9 +3986,14 @@ impl<Signer: Sign> Channel<Signer> {
|
||||
/// `cargo doc --document-private-items`):
|
||||
/// [`super::channelmanager::ChannelManager::force_close_without_broadcasting_txn`] and
|
||||
/// [`super::channelmanager::ChannelManager::force_close_all_channels_without_broadcasting_txn`].
|
||||
pub fn channel_reestablish<L: Deref>(&mut self, msg: &msgs::ChannelReestablish, logger: &L,
|
||||
node_pk: PublicKey, genesis_block_hash: BlockHash, user_config: &UserConfig, best_block: &BestBlock)
|
||||
-> Result<ReestablishResponses, ChannelError> where L::Target: Logger {
|
||||
pub fn channel_reestablish<L: Deref, NS: Deref>(
|
||||
&mut self, msg: &msgs::ChannelReestablish, logger: &L, node_signer: &NS,
|
||||
genesis_block_hash: BlockHash, user_config: &UserConfig, best_block: &BestBlock
|
||||
) -> Result<ReestablishResponses, ChannelError>
|
||||
where
|
||||
L::Target: Logger,
|
||||
NS::Target: NodeSigner
|
||||
{
|
||||
if self.channel_state & (ChannelState::PeerDisconnected as u32) == 0 {
|
||||
// While BOLT 2 doesn't indicate explicitly we should error this channel here, it
|
||||
// almost certainly indicates we are going to end up out-of-sync in some way, so we
|
||||
@ -4038,7 +4057,7 @@ impl<Signer: Sign> Channel<Signer> {
|
||||
})
|
||||
} else { None };
|
||||
|
||||
let announcement_sigs = self.get_announcement_sigs(node_pk, genesis_block_hash, user_config, best_block.height(), logger);
|
||||
let announcement_sigs = self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, best_block.height(), logger);
|
||||
|
||||
if self.channel_state & (ChannelState::FundingSent as u32) == ChannelState::FundingSent as u32 {
|
||||
// If we're waiting on a monitor update, we shouldn't re-send any channel_ready's.
|
||||
@ -5010,9 +5029,14 @@ impl<Signer: Sign> Channel<Signer> {
|
||||
/// When a transaction is confirmed, we check whether it is or spends the funding transaction
|
||||
/// In the first case, we store the confirmation height and calculating the short channel id.
|
||||
/// In the second, we simply return an Err indicating we need to be force-closed now.
|
||||
pub fn transactions_confirmed<L: Deref>(&mut self, block_hash: &BlockHash, height: u32,
|
||||
txdata: &TransactionData, genesis_block_hash: BlockHash, node_pk: PublicKey, user_config: &UserConfig, logger: &L)
|
||||
-> Result<(Option<msgs::ChannelReady>, Option<msgs::AnnouncementSignatures>), ClosureReason> where L::Target: Logger {
|
||||
pub fn transactions_confirmed<NS: Deref, L: Deref>(
|
||||
&mut self, block_hash: &BlockHash, height: u32, txdata: &TransactionData,
|
||||
genesis_block_hash: BlockHash, node_signer: &NS, user_config: &UserConfig, logger: &L
|
||||
) -> Result<(Option<msgs::ChannelReady>, Option<msgs::AnnouncementSignatures>), ClosureReason>
|
||||
where
|
||||
NS::Target: NodeSigner,
|
||||
L::Target: Logger
|
||||
{
|
||||
if let Some(funding_txo) = self.get_funding_txo() {
|
||||
for &(index_in_block, tx) in txdata.iter() {
|
||||
// Check if the transaction is the expected funding transaction, and if it is,
|
||||
@ -5058,7 +5082,7 @@ impl<Signer: Sign> Channel<Signer> {
|
||||
// may have already happened for this block).
|
||||
if let Some(channel_ready) = self.check_get_channel_ready(height) {
|
||||
log_info!(logger, "Sending a channel_ready to our peer for channel {}", log_bytes!(self.channel_id));
|
||||
let announcement_sigs = self.get_announcement_sigs(node_pk, genesis_block_hash, user_config, height, logger);
|
||||
let announcement_sigs = self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, height, logger);
|
||||
return Ok((Some(channel_ready), announcement_sigs));
|
||||
}
|
||||
}
|
||||
@ -5084,13 +5108,25 @@ impl<Signer: Sign> Channel<Signer> {
|
||||
///
|
||||
/// May return some HTLCs (and their payment_hash) which have timed out and should be failed
|
||||
/// back.
|
||||
pub fn best_block_updated<L: Deref>(&mut self, height: u32, highest_header_time: u32, genesis_block_hash: BlockHash, node_pk: PublicKey, user_config: UserConfig, logger: &L)
|
||||
-> Result<(Option<msgs::ChannelReady>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason> where L::Target: Logger {
|
||||
self.do_best_block_updated(height, highest_header_time, Some((genesis_block_hash, node_pk, user_config)), logger)
|
||||
pub fn best_block_updated<NS: Deref, L: Deref>(
|
||||
&mut self, height: u32, highest_header_time: u32, genesis_block_hash: BlockHash,
|
||||
node_signer: &NS, user_config: &UserConfig, logger: &L
|
||||
) -> Result<(Option<msgs::ChannelReady>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason>
|
||||
where
|
||||
NS::Target: NodeSigner,
|
||||
L::Target: Logger
|
||||
{
|
||||
self.do_best_block_updated(height, highest_header_time, Some((genesis_block_hash, node_signer, user_config)), logger)
|
||||
}
|
||||
|
||||
fn do_best_block_updated<L: Deref>(&mut self, height: u32, highest_header_time: u32, genesis_node_pk: Option<(BlockHash, PublicKey, UserConfig)>, logger: &L)
|
||||
-> Result<(Option<msgs::ChannelReady>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason> where L::Target: Logger {
|
||||
fn do_best_block_updated<NS: Deref, L: Deref>(
|
||||
&mut self, height: u32, highest_header_time: u32,
|
||||
genesis_node_signer: Option<(BlockHash, &NS, &UserConfig)>, logger: &L
|
||||
) -> Result<(Option<msgs::ChannelReady>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason>
|
||||
where
|
||||
NS::Target: NodeSigner,
|
||||
L::Target: Logger
|
||||
{
|
||||
let mut timed_out_htlcs = Vec::new();
|
||||
// This mirrors the check in ChannelManager::decode_update_add_htlc_onion, refusing to
|
||||
// forward an HTLC when our counterparty should almost certainly just fail it for expiring
|
||||
@ -5111,8 +5147,8 @@ impl<Signer: Sign> Channel<Signer> {
|
||||
self.update_time_counter = cmp::max(self.update_time_counter, highest_header_time);
|
||||
|
||||
if let Some(channel_ready) = self.check_get_channel_ready(height) {
|
||||
let announcement_sigs = if let Some((genesis_block_hash, node_pk, user_config)) = genesis_node_pk {
|
||||
self.get_announcement_sigs(node_pk, genesis_block_hash, &user_config, height, logger)
|
||||
let announcement_sigs = if let Some((genesis_block_hash, node_signer, user_config)) = genesis_node_signer {
|
||||
self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, height, logger)
|
||||
} else { None };
|
||||
log_info!(logger, "Sending a channel_ready to our peer for channel {}", log_bytes!(self.channel_id));
|
||||
return Ok((Some(channel_ready), timed_out_htlcs, announcement_sigs));
|
||||
@ -5152,8 +5188,8 @@ impl<Signer: Sign> Channel<Signer> {
|
||||
return Err(ClosureReason::FundingTimedOut);
|
||||
}
|
||||
|
||||
let announcement_sigs = if let Some((genesis_block_hash, node_pk, user_config)) = genesis_node_pk {
|
||||
self.get_announcement_sigs(node_pk, genesis_block_hash, &user_config, height, logger)
|
||||
let announcement_sigs = if let Some((genesis_block_hash, node_signer, user_config)) = genesis_node_signer {
|
||||
self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, height, logger)
|
||||
} else { None };
|
||||
Ok((None, timed_out_htlcs, announcement_sigs))
|
||||
}
|
||||
@ -5170,7 +5206,7 @@ impl<Signer: Sign> Channel<Signer> {
|
||||
// larger. If we don't know that time has moved forward, we can just set it to the last
|
||||
// time we saw and it will be ignored.
|
||||
let best_time = self.update_time_counter;
|
||||
match self.do_best_block_updated(reorg_height, best_time, None, logger) {
|
||||
match self.do_best_block_updated(reorg_height, best_time, None::<(BlockHash, &&NodeSigner, &UserConfig)>, logger) {
|
||||
Ok((channel_ready, timed_out_htlcs, announcement_sigs)) => {
|
||||
assert!(channel_ready.is_none(), "We can't generate a funding with 0 confirmations?");
|
||||
assert!(timed_out_htlcs.is_empty(), "We can't have accepted HTLCs with a timeout before our funding confirmation?");
|
||||
@ -5370,7 +5406,9 @@ impl<Signer: Sign> Channel<Signer> {
|
||||
/// closing).
|
||||
///
|
||||
/// This will only return ChannelError::Ignore upon failure.
|
||||
fn get_channel_announcement(&self, node_id: PublicKey, chain_hash: BlockHash, user_config: &UserConfig) -> Result<msgs::UnsignedChannelAnnouncement, ChannelError> {
|
||||
fn get_channel_announcement<NS: Deref>(
|
||||
&self, node_signer: &NS, chain_hash: BlockHash, user_config: &UserConfig,
|
||||
) -> Result<msgs::UnsignedChannelAnnouncement, ChannelError> where NS::Target: NodeSigner {
|
||||
if !self.config.announced_channel {
|
||||
return Err(ChannelError::Ignore("Channel is not available for public announcements".to_owned()));
|
||||
}
|
||||
@ -5378,6 +5416,8 @@ impl<Signer: Sign> Channel<Signer> {
|
||||
return Err(ChannelError::Ignore("Cannot get a ChannelAnnouncement if the channel is not currently usable".to_owned()));
|
||||
}
|
||||
|
||||
let node_id = node_signer.get_node_id(Recipient::Node)
|
||||
.map_err(|_| ChannelError::Ignore("Failed to retrieve own public key".to_owned()))?;
|
||||
let were_node_one = node_id.serialize()[..] < self.counterparty_node_id.serialize()[..];
|
||||
|
||||
let msg = msgs::UnsignedChannelAnnouncement {
|
||||
@ -5394,8 +5434,14 @@ impl<Signer: Sign> Channel<Signer> {
|
||||
Ok(msg)
|
||||
}
|
||||
|
||||
fn get_announcement_sigs<L: Deref>(&mut self, node_pk: PublicKey, genesis_block_hash: BlockHash, user_config: &UserConfig, best_block_height: u32, logger: &L)
|
||||
-> Option<msgs::AnnouncementSignatures> where L::Target: Logger {
|
||||
fn get_announcement_sigs<NS: Deref, L: Deref>(
|
||||
&mut self, node_signer: &NS, genesis_block_hash: BlockHash, user_config: &UserConfig,
|
||||
best_block_height: u32, logger: &L
|
||||
) -> Option<msgs::AnnouncementSignatures>
|
||||
where
|
||||
NS::Target: NodeSigner,
|
||||
L::Target: Logger
|
||||
{
|
||||
if self.funding_tx_confirmation_height == 0 || self.funding_tx_confirmation_height + 5 > best_block_height {
|
||||
return None;
|
||||
}
|
||||
@ -5414,14 +5460,21 @@ impl<Signer: Sign> Channel<Signer> {
|
||||
}
|
||||
|
||||
log_trace!(logger, "Creating an announcement_signatures message for channel {}", log_bytes!(self.channel_id()));
|
||||
let announcement = match self.get_channel_announcement(node_pk, genesis_block_hash, user_config) {
|
||||
let announcement = match self.get_channel_announcement(node_signer, genesis_block_hash, user_config) {
|
||||
Ok(a) => a,
|
||||
Err(_) => {
|
||||
log_trace!(logger, "Cannot create an announcement_signatures as channel is not public.");
|
||||
Err(e) => {
|
||||
log_trace!(logger, "{:?}", e);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
let (our_node_sig, our_bitcoin_sig) = match self.holder_signer.sign_channel_announcement(&announcement, &self.secp_ctx) {
|
||||
let our_node_sig = match node_signer.sign_gossip_message(msgs::UnsignedGossipMessage::ChannelAnnouncement(&announcement)) {
|
||||
Err(_) => {
|
||||
log_error!(logger, "Failed to generate node signature for channel_announcement. Channel will not be announced!");
|
||||
return None;
|
||||
},
|
||||
Ok(v) => v
|
||||
};
|
||||
let our_bitcoin_sig = match self.holder_signer.sign_channel_announcement_with_funding_key(&announcement, &self.secp_ctx) {
|
||||
Err(_) => {
|
||||
log_error!(logger, "Signer rejected channel_announcement signing. Channel will not be announced!");
|
||||
return None;
|
||||
@ -5440,11 +5493,17 @@ impl<Signer: Sign> Channel<Signer> {
|
||||
|
||||
/// Signs the given channel announcement, returning a ChannelError::Ignore if no keys are
|
||||
/// available.
|
||||
fn sign_channel_announcement(&self, our_node_id: PublicKey, announcement: msgs::UnsignedChannelAnnouncement) -> Result<msgs::ChannelAnnouncement, ChannelError> {
|
||||
fn sign_channel_announcement<NS: Deref>(
|
||||
&self, node_signer: &NS, announcement: msgs::UnsignedChannelAnnouncement
|
||||
) -> Result<msgs::ChannelAnnouncement, ChannelError> where NS::Target: NodeSigner {
|
||||
if let Some((their_node_sig, their_bitcoin_sig)) = self.announcement_sigs {
|
||||
let were_node_one = announcement.node_id_1 == our_node_id;
|
||||
let our_node_key = node_signer.get_node_id(Recipient::Node)
|
||||
.map_err(|_| ChannelError::Ignore("Signer failed to retrieve own public key".to_owned()))?;
|
||||
let were_node_one = announcement.node_id_1 == our_node_key;
|
||||
|
||||
let (our_node_sig, our_bitcoin_sig) = self.holder_signer.sign_channel_announcement(&announcement, &self.secp_ctx)
|
||||
let our_node_sig = node_signer.sign_gossip_message(msgs::UnsignedGossipMessage::ChannelAnnouncement(&announcement))
|
||||
.map_err(|_| ChannelError::Ignore("Failed to generate node signature for channel_announcement".to_owned()))?;
|
||||
let our_bitcoin_sig = self.holder_signer.sign_channel_announcement_with_funding_key(&announcement, &self.secp_ctx)
|
||||
.map_err(|_| ChannelError::Ignore("Signer rejected channel_announcement".to_owned()))?;
|
||||
Ok(msgs::ChannelAnnouncement {
|
||||
node_signature_1: if were_node_one { our_node_sig } else { their_node_sig },
|
||||
@ -5461,8 +5520,11 @@ impl<Signer: Sign> Channel<Signer> {
|
||||
/// Processes an incoming announcement_signatures message, providing a fully-signed
|
||||
/// channel_announcement message which we can broadcast and storing our counterparty's
|
||||
/// signatures for later reconstruction/rebroadcast of the channel_announcement.
|
||||
pub fn announcement_signatures(&mut self, our_node_id: PublicKey, chain_hash: BlockHash, best_block_height: u32, msg: &msgs::AnnouncementSignatures, user_config: &UserConfig) -> Result<msgs::ChannelAnnouncement, ChannelError> {
|
||||
let announcement = self.get_channel_announcement(our_node_id.clone(), chain_hash, user_config)?;
|
||||
pub fn announcement_signatures<NS: Deref>(
|
||||
&mut self, node_signer: &NS, chain_hash: BlockHash, best_block_height: u32,
|
||||
msg: &msgs::AnnouncementSignatures, user_config: &UserConfig
|
||||
) -> Result<msgs::ChannelAnnouncement, ChannelError> where NS::Target: NodeSigner {
|
||||
let announcement = self.get_channel_announcement(node_signer, chain_hash, user_config)?;
|
||||
|
||||
let msghash = hash_to_message!(&Sha256d::hash(&announcement.encode()[..])[..]);
|
||||
|
||||
@ -5483,20 +5545,22 @@ impl<Signer: Sign> Channel<Signer> {
|
||||
"Got announcement_signatures prior to the required six confirmations - we may not have received a block yet that our peer has".to_owned()));
|
||||
}
|
||||
|
||||
self.sign_channel_announcement(our_node_id, announcement)
|
||||
self.sign_channel_announcement(node_signer, announcement)
|
||||
}
|
||||
|
||||
/// Gets a signed channel_announcement for this channel, if we previously received an
|
||||
/// announcement_signatures from our counterparty.
|
||||
pub fn get_signed_channel_announcement(&self, our_node_id: PublicKey, chain_hash: BlockHash, best_block_height: u32, user_config: &UserConfig) -> Option<msgs::ChannelAnnouncement> {
|
||||
pub fn get_signed_channel_announcement<NS: Deref>(
|
||||
&self, node_signer: &NS, chain_hash: BlockHash, best_block_height: u32, user_config: &UserConfig
|
||||
) -> Option<msgs::ChannelAnnouncement> where NS::Target: NodeSigner {
|
||||
if self.funding_tx_confirmation_height == 0 || self.funding_tx_confirmation_height + 5 > best_block_height {
|
||||
return None;
|
||||
}
|
||||
let announcement = match self.get_channel_announcement(our_node_id.clone(), chain_hash, user_config) {
|
||||
let announcement = match self.get_channel_announcement(node_signer, chain_hash, user_config) {
|
||||
Ok(res) => res,
|
||||
Err(_) => return None,
|
||||
};
|
||||
match self.sign_channel_announcement(our_node_id, announcement) {
|
||||
match self.sign_channel_announcement(node_signer, announcement) {
|
||||
Ok(res) => Some(res),
|
||||
Err(_) => None,
|
||||
}
|
||||
@ -6837,22 +6901,19 @@ 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, EntropySource, NodeSigner, SignerProvider};
|
||||
use crate::chain::keysinterface::{BaseSign, InMemorySigner, EntropySource, SignerProvider};
|
||||
use crate::chain::transaction::OutPoint;
|
||||
use crate::util::config::UserConfig;
|
||||
use crate::util::enforcing_trait_impls::EnforcingSigner;
|
||||
use crate::util::errors::APIError;
|
||||
use crate::util::test_utils;
|
||||
use crate::util::test_utils::OnGetShutdownScriptpubkey;
|
||||
use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature, Scalar};
|
||||
use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
|
||||
use bitcoin::secp256k1::ffi::Signature as FFISignature;
|
||||
use bitcoin::secp256k1::{SecretKey,PublicKey};
|
||||
use bitcoin::secp256k1::ecdh::SharedSecret;
|
||||
use bitcoin::secp256k1::ecdsa::RecoverableSignature;
|
||||
use bitcoin::hashes::sha256::Hash as Sha256;
|
||||
use bitcoin::hashes::Hash;
|
||||
use bitcoin::hash_types::WPubkeyHash;
|
||||
use bitcoin::bech32::u5;
|
||||
use bitcoin::PackedLockTime;
|
||||
use bitcoin::util::address::WitnessVersion;
|
||||
use crate::prelude::*;
|
||||
@ -6891,21 +6952,6 @@ mod tests {
|
||||
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;
|
||||
|
||||
@ -7374,7 +7420,6 @@ mod tests {
|
||||
|
||||
let mut signer = InMemorySigner::new(
|
||||
&secp_ctx,
|
||||
SecretKey::from_slice(&hex::decode("4242424242424242424242424242424242424242424242424242424242424242").unwrap()[..]).unwrap(),
|
||||
SecretKey::from_slice(&hex::decode("30ff4956bbdd3222d44cc5e8a1261dab1e07957bdac5ae88fe3261ef321f3749").unwrap()[..]).unwrap(),
|
||||
SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(),
|
||||
SecretKey::from_slice(&hex::decode("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..]).unwrap(),
|
||||
|
@ -26,12 +26,10 @@ use bitcoin::network::constants::Network;
|
||||
|
||||
use bitcoin::hashes::Hash;
|
||||
use bitcoin::hashes::sha256::Hash as Sha256;
|
||||
use bitcoin::hashes::sha256d::Hash as Sha256dHash;
|
||||
use bitcoin::hash_types::{BlockHash, Txid};
|
||||
|
||||
use bitcoin::secp256k1::{SecretKey,PublicKey};
|
||||
use bitcoin::secp256k1::Secp256k1;
|
||||
use bitcoin::secp256k1::ecdh::SharedSecret;
|
||||
use bitcoin::{LockTime, secp256k1, Sequence};
|
||||
|
||||
use crate::chain;
|
||||
@ -721,7 +719,6 @@ where
|
||||
#[cfg(not(test))]
|
||||
short_to_chan_info: FairRwLock<HashMap<u64, (PublicKey, [u8; 32])>>,
|
||||
|
||||
our_network_key: SecretKey,
|
||||
our_network_pubkey: PublicKey,
|
||||
|
||||
inbound_payment_key: inbound_payment::ExpandedKey,
|
||||
@ -1457,8 +1454,7 @@ where
|
||||
id_to_peer: Mutex::new(HashMap::new()),
|
||||
short_to_chan_info: FairRwLock::new(HashMap::new()),
|
||||
|
||||
our_network_key: node_signer.get_node_secret(Recipient::Node).unwrap(),
|
||||
our_network_pubkey: PublicKey::from_secret_key(&secp_ctx, &node_signer.get_node_secret(Recipient::Node).unwrap()),
|
||||
our_network_pubkey: node_signer.get_node_id(Recipient::Node).unwrap(),
|
||||
secp_ctx,
|
||||
|
||||
inbound_payment_key: expanded_inbound_key,
|
||||
@ -2017,7 +2013,9 @@ where
|
||||
return_malformed_err!("invalid ephemeral pubkey", 0x8000 | 0x4000 | 6);
|
||||
}
|
||||
|
||||
let shared_secret = SharedSecret::new(&msg.onion_routing_packet.public_key.unwrap(), &self.our_network_key).secret_bytes();
|
||||
let shared_secret = self.node_signer.ecdh(
|
||||
Recipient::Node, &msg.onion_routing_packet.public_key.unwrap(), None
|
||||
).unwrap().secret_bytes();
|
||||
|
||||
if msg.onion_routing_packet.version != 0 {
|
||||
//TODO: Spec doesn't indicate if we should only hash hop_data here (and in other
|
||||
@ -2266,7 +2264,7 @@ where
|
||||
}
|
||||
fn get_channel_update_for_onion(&self, short_channel_id: u64, chan: &Channel<<SP::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()[..];
|
||||
let were_node_one = self.our_network_pubkey.serialize()[..] < chan.get_counterparty_node_id().serialize()[..];
|
||||
|
||||
let unsigned = msgs::UnsignedChannelUpdate {
|
||||
chain_hash: self.genesis_hash,
|
||||
@ -2280,9 +2278,11 @@ where
|
||||
fee_proportional_millionths: chan.get_fee_proportional_millionths(),
|
||||
excess_data: Vec::new(),
|
||||
};
|
||||
|
||||
let msg_hash = Sha256dHash::hash(&unsigned.encode()[..]);
|
||||
let sig = self.secp_ctx.sign_ecdsa(&hash_to_message!(&msg_hash[..]), &self.our_network_key);
|
||||
// Panic on failure to signal LDK should be restarted to retry signing the `ChannelUpdate`.
|
||||
// If we returned an error and the `node_signer` cannot provide a signature for whatever
|
||||
// reason`, we wouldn't be able to receive inbound payments through the corresponding
|
||||
// channel.
|
||||
let sig = self.node_signer.sign_gossip_message(msgs::UnsignedGossipMessage::ChannelUpdate(&unsigned)).unwrap();
|
||||
|
||||
Ok(msgs::ChannelUpdate {
|
||||
signature: sig,
|
||||
@ -2923,9 +2923,9 @@ where
|
||||
}
|
||||
}
|
||||
if let PendingHTLCRouting::Forward { onion_packet, .. } = routing {
|
||||
let phantom_secret_res = self.node_signer.get_node_secret(Recipient::PhantomNode);
|
||||
if phantom_secret_res.is_ok() && fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, short_chan_id, &self.genesis_hash) {
|
||||
let phantom_shared_secret = SharedSecret::new(&onion_packet.public_key.unwrap(), &phantom_secret_res.unwrap()).secret_bytes();
|
||||
let phantom_pubkey_res = self.node_signer.get_node_id(Recipient::PhantomNode);
|
||||
if phantom_pubkey_res.is_ok() && fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, short_chan_id, &self.genesis_hash) {
|
||||
let phantom_shared_secret = self.node_signer.ecdh(Recipient::PhantomNode, &onion_packet.public_key.unwrap(), None).unwrap().secret_bytes();
|
||||
let next_hop = match onion_utils::decode_next_payment_hop(phantom_shared_secret, &onion_packet.hop_data, onion_packet.hmac, payment_hash) {
|
||||
Ok(res) => res,
|
||||
Err(onion_utils::OnionDecodeErr::Malformed { err_msg, err_code }) => {
|
||||
@ -4060,7 +4060,7 @@ where
|
||||
return;
|
||||
}
|
||||
|
||||
let updates = channel.get_mut().monitor_updating_restored(&self.logger, self.get_our_node_id(), self.genesis_hash, &self.default_configuration, self.best_block.read().unwrap().height());
|
||||
let updates = channel.get_mut().monitor_updating_restored(&self.logger, &self.node_signer, self.genesis_hash, &self.default_configuration, self.best_block.read().unwrap().height());
|
||||
let channel_update = if updates.channel_ready.is_some() && channel.get().is_usable() {
|
||||
// We only send a channel_update in the case where we are just now sending a
|
||||
// channel_ready and the channel is in a usable state. We may re-send a
|
||||
@ -4397,7 +4397,7 @@ where
|
||||
let peer_state = &mut *peer_state_lock;
|
||||
match peer_state.channel_by_id.entry(msg.channel_id) {
|
||||
hash_map::Entry::Occupied(mut chan) => {
|
||||
let announcement_sigs_opt = try_chan_entry!(self, chan.get_mut().channel_ready(&msg, self.get_our_node_id(),
|
||||
let announcement_sigs_opt = try_chan_entry!(self, chan.get_mut().channel_ready(&msg, &self.node_signer,
|
||||
self.genesis_hash.clone(), &self.default_configuration, &self.best_block.read().unwrap(), &self.logger), chan);
|
||||
if let Some(announcement_sigs) = announcement_sigs_opt {
|
||||
log_trace!(self.logger, "Sending announcement_signatures for channel {}", log_bytes!(chan.get().channel_id()));
|
||||
@ -4879,8 +4879,8 @@ where
|
||||
|
||||
peer_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelAnnouncement {
|
||||
msg: try_chan_entry!(self, chan.get_mut().announcement_signatures(
|
||||
self.get_our_node_id(), self.genesis_hash.clone(),
|
||||
self.best_block.read().unwrap().height(), msg, &self.default_configuration
|
||||
&self.node_signer, self.genesis_hash.clone(), self.best_block.read().unwrap().height(),
|
||||
msg, &self.default_configuration
|
||||
), chan),
|
||||
// Note that announcement_signatures fails if the channel cannot be announced,
|
||||
// so get_channel_update_for_broadcast will never fail by the time we get here.
|
||||
@ -4951,7 +4951,7 @@ where
|
||||
// freed HTLCs to fail backwards. If in the future we no longer drop pending
|
||||
// add-HTLCs on disconnect, we may be handed HTLCs to fail backwards here.
|
||||
let responses = try_chan_entry!(self, chan.get_mut().channel_reestablish(
|
||||
msg, &self.logger, self.our_network_pubkey.clone(), self.genesis_hash,
|
||||
msg, &self.logger, &self.node_signer, self.genesis_hash,
|
||||
&self.default_configuration, &*self.best_block.read().unwrap()), chan);
|
||||
let mut channel_update = None;
|
||||
if let Some(msg) = responses.shutdown_msg {
|
||||
@ -5630,7 +5630,7 @@ where
|
||||
*best_block = BestBlock::new(header.prev_blockhash, new_height)
|
||||
}
|
||||
|
||||
self.do_chain_event(Some(new_height), |channel| channel.best_block_updated(new_height, header.time, self.genesis_hash.clone(), self.get_our_node_id(), self.default_configuration.clone(), &self.logger));
|
||||
self.do_chain_event(Some(new_height), |channel| channel.best_block_updated(new_height, header.time, self.genesis_hash.clone(), &self.node_signer, &self.default_configuration, &self.logger));
|
||||
}
|
||||
}
|
||||
|
||||
@ -5654,13 +5654,13 @@ where
|
||||
log_trace!(self.logger, "{} transactions included in block {} at height {} provided", txdata.len(), block_hash, height);
|
||||
|
||||
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
|
||||
self.do_chain_event(Some(height), |channel| channel.transactions_confirmed(&block_hash, height, txdata, self.genesis_hash.clone(), self.get_our_node_id(), &self.default_configuration, &self.logger)
|
||||
self.do_chain_event(Some(height), |channel| channel.transactions_confirmed(&block_hash, height, txdata, self.genesis_hash.clone(), &self.node_signer, &self.default_configuration, &self.logger)
|
||||
.map(|(a, b)| (a, Vec::new(), b)));
|
||||
|
||||
let last_best_block_height = self.best_block.read().unwrap().height();
|
||||
if height < last_best_block_height {
|
||||
let timestamp = self.highest_seen_timestamp.load(Ordering::Acquire);
|
||||
self.do_chain_event(Some(last_best_block_height), |channel| channel.best_block_updated(last_best_block_height, timestamp as u32, self.genesis_hash.clone(), self.get_our_node_id(), self.default_configuration.clone(), &self.logger));
|
||||
self.do_chain_event(Some(last_best_block_height), |channel| channel.best_block_updated(last_best_block_height, timestamp as u32, self.genesis_hash.clone(), &self.node_signer, &self.default_configuration, &self.logger));
|
||||
}
|
||||
}
|
||||
|
||||
@ -5676,7 +5676,7 @@ where
|
||||
|
||||
*self.best_block.write().unwrap() = BestBlock::new(block_hash, height);
|
||||
|
||||
self.do_chain_event(Some(height), |channel| channel.best_block_updated(height, header.time, self.genesis_hash.clone(), self.get_our_node_id(), self.default_configuration.clone(), &self.logger));
|
||||
self.do_chain_event(Some(height), |channel| channel.best_block_updated(height, header.time, self.genesis_hash.clone(), &self.node_signer, &self.default_configuration, &self.logger));
|
||||
|
||||
macro_rules! max_time {
|
||||
($timestamp: expr) => {
|
||||
@ -5787,7 +5787,7 @@ where
|
||||
msg: announcement_sigs,
|
||||
});
|
||||
if let Some(height) = height_opt {
|
||||
if let Some(announcement) = channel.get_signed_channel_announcement(self.get_our_node_id(), self.genesis_hash, height, &self.default_configuration) {
|
||||
if let Some(announcement) = channel.get_signed_channel_announcement(&self.node_signer, self.genesis_hash, height, &self.default_configuration) {
|
||||
pending_msg_events.push(events::MessageSendEvent::BroadcastChannelAnnouncement {
|
||||
msg: announcement,
|
||||
// Note that announcement_signatures fails if the channel cannot be announced,
|
||||
@ -6177,7 +6177,7 @@ where
|
||||
}
|
||||
} else { true };
|
||||
if retain && chan.get_counterparty_node_id() != *counterparty_node_id {
|
||||
if let Some(msg) = chan.get_signed_channel_announcement(self.get_our_node_id(), self.genesis_hash.clone(), self.best_block.read().unwrap().height(), &self.default_configuration) {
|
||||
if let Some(msg) = chan.get_signed_channel_announcement(&self.node_signer, self.genesis_hash.clone(), self.best_block.read().unwrap().height(), &self.default_configuration) {
|
||||
if let Ok(update_msg) = self.get_channel_update_for_broadcast(chan) {
|
||||
pending_msg_events.push(events::MessageSendEvent::SendChannelAnnouncement {
|
||||
node_id: *counterparty_node_id,
|
||||
@ -7394,11 +7394,10 @@ where
|
||||
pending_events_read.append(&mut channel_closures);
|
||||
}
|
||||
|
||||
let our_network_key = match args.node_signer.get_node_secret(Recipient::Node) {
|
||||
let our_network_pubkey = match args.node_signer.get_node_id(Recipient::Node) {
|
||||
Ok(key) => key,
|
||||
Err(()) => return Err(DecodeError::InvalidValue)
|
||||
};
|
||||
let our_network_pubkey = PublicKey::from_secret_key(&secp_ctx, &our_network_key);
|
||||
if let Some(network_pubkey) = received_network_pubkey {
|
||||
if network_pubkey != our_network_pubkey {
|
||||
log_error!(args.logger, "Key that was generated does not match the existing key.");
|
||||
@ -7514,7 +7513,6 @@ where
|
||||
|
||||
probing_cookie_secret: probing_cookie_secret.unwrap(),
|
||||
|
||||
our_network_key,
|
||||
our_network_pubkey,
|
||||
secp_ctx,
|
||||
|
||||
|
@ -632,6 +632,25 @@ impl Readable for NetAddress {
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents the set of gossip messages that require a signature from a node's identity key.
|
||||
pub enum UnsignedGossipMessage<'a> {
|
||||
/// An unsigned channel announcement.
|
||||
ChannelAnnouncement(&'a UnsignedChannelAnnouncement),
|
||||
/// An unsigned channel update.
|
||||
ChannelUpdate(&'a UnsignedChannelUpdate),
|
||||
/// An unsigned node announcement.
|
||||
NodeAnnouncement(&'a UnsignedNodeAnnouncement)
|
||||
}
|
||||
|
||||
impl<'a> Writeable for UnsignedGossipMessage<'a> {
|
||||
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
|
||||
match self {
|
||||
UnsignedGossipMessage::ChannelAnnouncement(ref msg) => msg.write(writer),
|
||||
UnsignedGossipMessage::ChannelUpdate(ref msg) => msg.write(writer),
|
||||
UnsignedGossipMessage::NodeAnnouncement(ref msg) => msg.write(writer),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The unsigned part of a [`node_announcement`] message.
|
||||
///
|
||||
|
@ -35,8 +35,7 @@ use bitcoin::hashes::Hash;
|
||||
use bitcoin::hashes::sha256::Hash as Sha256;
|
||||
|
||||
use bitcoin::secp256k1;
|
||||
use bitcoin::secp256k1::Secp256k1;
|
||||
use bitcoin::secp256k1::{PublicKey, SecretKey};
|
||||
use bitcoin::secp256k1::{Secp256k1, SecretKey};
|
||||
|
||||
use crate::io;
|
||||
use crate::prelude::*;
|
||||
@ -834,9 +833,7 @@ fn test_always_create_tlv_format_onion_payloads() {
|
||||
|
||||
macro_rules! get_phantom_route {
|
||||
($nodes: expr, $amt: expr, $channel: expr) => {{
|
||||
let secp_ctx = Secp256k1::new();
|
||||
let phantom_secret = $nodes[1].keys_manager.get_node_secret(Recipient::PhantomNode).unwrap();
|
||||
let phantom_pubkey = PublicKey::from_secret_key(&secp_ctx, &phantom_secret);
|
||||
let phantom_pubkey = $nodes[1].keys_manager.get_node_id(Recipient::PhantomNode).unwrap();
|
||||
let phantom_route_hint = $nodes[1].node.get_phantom_route_hints();
|
||||
let payment_params = PaymentParameters::from_node_id(phantom_pubkey)
|
||||
.with_features($nodes[1].node.invoice_features())
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use crate::chain::keysinterface::{NodeSigner, Recipient};
|
||||
use crate::ln::msgs::LightningError;
|
||||
use crate::ln::msgs;
|
||||
use crate::ln::wire;
|
||||
@ -26,6 +27,8 @@ use crate::util::crypto::hkdf_extract_expand_twice;
|
||||
use crate::util::ser::VecWriter;
|
||||
use bitcoin::hashes::hex::ToHex;
|
||||
|
||||
use core::ops::Deref;
|
||||
|
||||
/// Maximum Lightning message data length according to
|
||||
/// [BOLT-8](https://github.com/lightning/bolts/blob/v1.0/08-transport.md#lightning-message-specification)
|
||||
/// and [BOLT-1](https://github.com/lightning/bolts/blob/master/01-messaging.md#lightning-message-format):
|
||||
@ -36,6 +39,11 @@ const NOISE_CK: [u8; 32] = [0x26, 0x40, 0xf5, 0x2e, 0xeb, 0xcd, 0x9e, 0x88, 0x29
|
||||
// Sha256(NOISE_CK || "lightning")
|
||||
const NOISE_H: [u8; 32] = [0xd1, 0xfb, 0xf6, 0xde, 0xe4, 0xf6, 0x86, 0xf1, 0x32, 0xfd, 0x70, 0x2c, 0x4a, 0xbf, 0x8f, 0xba, 0x4b, 0xb4, 0x20, 0xd8, 0x9d, 0x2a, 0x04, 0x8a, 0x3c, 0x4f, 0x4c, 0x09, 0x2e, 0x37, 0xb6, 0x76];
|
||||
|
||||
enum NoiseSecretKey<'a, 'b, NS: Deref> where NS::Target: NodeSigner {
|
||||
InMemory(&'a SecretKey),
|
||||
NodeSigner(&'b NS)
|
||||
}
|
||||
|
||||
pub enum NextNoiseStep {
|
||||
ActOne,
|
||||
ActTwo,
|
||||
@ -109,10 +117,10 @@ impl PeerChannelEncryptor {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_inbound<C: secp256k1::Signing>(our_node_secret: &SecretKey, secp_ctx: &Secp256k1<C>) -> PeerChannelEncryptor {
|
||||
pub fn new_inbound<NS: Deref>(node_signer: &NS) -> PeerChannelEncryptor where NS::Target: NodeSigner {
|
||||
let mut sha = Sha256::engine();
|
||||
sha.input(&NOISE_H);
|
||||
let our_node_id = PublicKey::from_secret_key(&secp_ctx, our_node_secret);
|
||||
let our_node_id = node_signer.get_node_id(Recipient::Node).unwrap();
|
||||
sha.input(&our_node_id.serialize()[..]);
|
||||
let h = Sha256::from_engine(sha).into_inner();
|
||||
|
||||
@ -201,7 +209,9 @@ impl PeerChannelEncryptor {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inbound_noise_act(state: &mut BidirectionalNoiseState, act: &[u8], our_key: &SecretKey) -> Result<(PublicKey, [u8; 32]), LightningError> {
|
||||
fn inbound_noise_act<'a, 'b, NS: Deref>(
|
||||
state: &mut BidirectionalNoiseState, act: &[u8], secret_key: NoiseSecretKey<'a, 'b, NS>
|
||||
) -> Result<(PublicKey, [u8; 32]), LightningError> where NS::Target: NodeSigner {
|
||||
assert_eq!(act.len(), 50);
|
||||
|
||||
if act[0] != 0 {
|
||||
@ -218,7 +228,15 @@ impl PeerChannelEncryptor {
|
||||
sha.input(&their_pub.serialize()[..]);
|
||||
state.h = Sha256::from_engine(sha).into_inner();
|
||||
|
||||
let ss = SharedSecret::new(&their_pub, &our_key);
|
||||
let ss = match secret_key {
|
||||
NoiseSecretKey::InMemory(secret_key) => SharedSecret::new(&their_pub, secret_key),
|
||||
NoiseSecretKey::NodeSigner(node_signer) => node_signer
|
||||
.ecdh(Recipient::Node, &their_pub, None)
|
||||
.map_err(|_| LightningError {
|
||||
err: "Failed to derive shared secret".to_owned(),
|
||||
action: msgs::ErrorAction::DisconnectPeer { msg: None }
|
||||
})?,
|
||||
};
|
||||
let temp_k = PeerChannelEncryptor::hkdf(state, ss);
|
||||
|
||||
let mut dec = [0; 0];
|
||||
@ -251,9 +269,9 @@ impl PeerChannelEncryptor {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn process_act_one_with_keys<C: secp256k1::Signing>(
|
||||
&mut self, act_one: &[u8], our_node_secret: &SecretKey, our_ephemeral: SecretKey, secp_ctx: &Secp256k1<C>)
|
||||
-> Result<[u8; 50], LightningError> {
|
||||
pub fn process_act_one_with_keys<C: secp256k1::Signing, NS: Deref>(
|
||||
&mut self, act_one: &[u8], node_signer: &NS, our_ephemeral: SecretKey, secp_ctx: &Secp256k1<C>)
|
||||
-> Result<[u8; 50], LightningError> where NS::Target: NodeSigner {
|
||||
assert_eq!(act_one.len(), 50);
|
||||
|
||||
match self.noise_state {
|
||||
@ -264,7 +282,7 @@ impl PeerChannelEncryptor {
|
||||
panic!("Requested act at wrong step");
|
||||
}
|
||||
|
||||
let (their_pub, _) = PeerChannelEncryptor::inbound_noise_act(bidirectional_state, act_one, &our_node_secret)?;
|
||||
let (their_pub, _) = PeerChannelEncryptor::inbound_noise_act(bidirectional_state, act_one, NoiseSecretKey::NodeSigner(node_signer))?;
|
||||
ie.get_or_insert(their_pub);
|
||||
|
||||
re.get_or_insert(our_ephemeral);
|
||||
@ -281,9 +299,9 @@ impl PeerChannelEncryptor {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn process_act_two<C: secp256k1::Signing>(
|
||||
&mut self, act_two: &[u8], our_node_secret: &SecretKey, secp_ctx: &Secp256k1<C>)
|
||||
-> Result<([u8; 66], PublicKey), LightningError> {
|
||||
pub fn process_act_two<NS: Deref>(
|
||||
&mut self, act_two: &[u8], node_signer: &NS)
|
||||
-> Result<([u8; 66], PublicKey), LightningError> where NS::Target: NodeSigner {
|
||||
assert_eq!(act_two.len(), 50);
|
||||
|
||||
let final_hkdf;
|
||||
@ -296,10 +314,13 @@ impl PeerChannelEncryptor {
|
||||
panic!("Requested act at wrong step");
|
||||
}
|
||||
|
||||
let (re, temp_k2) = PeerChannelEncryptor::inbound_noise_act(bidirectional_state, act_two, &ie)?;
|
||||
let (re, temp_k2) = PeerChannelEncryptor::inbound_noise_act(bidirectional_state, act_two, NoiseSecretKey::<NS>::InMemory(&ie))?;
|
||||
|
||||
let mut res = [0; 66];
|
||||
let our_node_id = PublicKey::from_secret_key(secp_ctx, &our_node_secret);
|
||||
let our_node_id = node_signer.get_node_id(Recipient::Node).map_err(|_| LightningError {
|
||||
err: "Failed to encrypt message".to_owned(),
|
||||
action: msgs::ErrorAction::DisconnectPeer { msg: None }
|
||||
})?;
|
||||
|
||||
PeerChannelEncryptor::encrypt_with_ad(&mut res[1..50], 1, &temp_k2, &bidirectional_state.h, &our_node_id.serialize()[..]);
|
||||
|
||||
@ -308,7 +329,10 @@ impl PeerChannelEncryptor {
|
||||
sha.input(&res[1..50]);
|
||||
bidirectional_state.h = Sha256::from_engine(sha).into_inner();
|
||||
|
||||
let ss = SharedSecret::new(&re, our_node_secret);
|
||||
let ss = node_signer.ecdh(Recipient::Node, &re, None).map_err(|_| LightningError {
|
||||
err: "Failed to derive shared secret".to_owned(),
|
||||
action: msgs::ErrorAction::DisconnectPeer { msg: None }
|
||||
})?;
|
||||
let temp_k = PeerChannelEncryptor::hkdf(bidirectional_state, ss);
|
||||
|
||||
PeerChannelEncryptor::encrypt_with_ad(&mut res[50..], 0, &temp_k, &bidirectional_state.h, &[0; 0]);
|
||||
@ -522,12 +546,13 @@ impl PeerChannelEncryptor {
|
||||
mod tests {
|
||||
use super::LN_MAX_MSG_LEN;
|
||||
|
||||
use bitcoin::secp256k1::{PublicKey,SecretKey};
|
||||
use bitcoin::secp256k1::{PublicKey, SecretKey};
|
||||
use bitcoin::secp256k1::Secp256k1;
|
||||
|
||||
use hex;
|
||||
|
||||
use crate::ln::peer_channel_encryptor::{PeerChannelEncryptor,NoiseState};
|
||||
use crate::util::test_utils::TestNodeSigner;
|
||||
|
||||
fn get_outbound_peer_for_initiator_test_vectors() -> PeerChannelEncryptor {
|
||||
let their_node_id = PublicKey::from_slice(&hex::decode("028d7500dd4c12685d1f568b4c2b5048e8534b873319f3a8daa612b469132ec7f7").unwrap()[..]).unwrap();
|
||||
@ -542,12 +567,13 @@ mod tests {
|
||||
// transport-responder successful handshake
|
||||
let our_node_id = SecretKey::from_slice(&hex::decode("2121212121212121212121212121212121212121212121212121212121212121").unwrap()[..]).unwrap();
|
||||
let our_ephemeral = SecretKey::from_slice(&hex::decode("2222222222222222222222222222222222222222222222222222222222222222").unwrap()[..]).unwrap();
|
||||
let secp_ctx = Secp256k1::signing_only();
|
||||
let secp_ctx = Secp256k1::new();
|
||||
let node_signer = TestNodeSigner::new(our_node_id);
|
||||
|
||||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id, &secp_ctx);
|
||||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&&node_signer);
|
||||
|
||||
let act_one = hex::decode("00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a").unwrap().to_vec();
|
||||
assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone(), &secp_ctx).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
|
||||
assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &&node_signer, our_ephemeral.clone(), &secp_ctx).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
|
||||
|
||||
let act_three = hex::decode("00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba").unwrap().to_vec();
|
||||
// test vector doesn't specify the initiator static key, but it's the same as the one
|
||||
@ -572,14 +598,14 @@ mod tests {
|
||||
#[test]
|
||||
fn noise_initiator_test_vectors() {
|
||||
let our_node_id = SecretKey::from_slice(&hex::decode("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..]).unwrap();
|
||||
let secp_ctx = Secp256k1::signing_only();
|
||||
let node_signer = TestNodeSigner::new(our_node_id);
|
||||
|
||||
{
|
||||
// transport-initiator successful handshake
|
||||
let mut outbound_peer = get_outbound_peer_for_initiator_test_vectors();
|
||||
|
||||
let act_two = hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap().to_vec();
|
||||
assert_eq!(outbound_peer.process_act_two(&act_two[..], &our_node_id, &secp_ctx).unwrap().0[..], hex::decode("00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba").unwrap()[..]);
|
||||
assert_eq!(outbound_peer.process_act_two(&act_two[..], &&node_signer).unwrap().0[..], hex::decode("00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba").unwrap()[..]);
|
||||
|
||||
match outbound_peer.noise_state {
|
||||
NoiseState::Finished { sk, sn, sck, rk, rn, rck } => {
|
||||
@ -602,7 +628,7 @@ mod tests {
|
||||
let mut outbound_peer = get_outbound_peer_for_initiator_test_vectors();
|
||||
|
||||
let act_two = hex::decode("0102466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap().to_vec();
|
||||
assert!(outbound_peer.process_act_two(&act_two[..], &our_node_id, &secp_ctx).is_err());
|
||||
assert!(outbound_peer.process_act_two(&act_two[..], &&node_signer).is_err());
|
||||
}
|
||||
|
||||
{
|
||||
@ -610,7 +636,7 @@ mod tests {
|
||||
let mut outbound_peer = get_outbound_peer_for_initiator_test_vectors();
|
||||
|
||||
let act_two = hex::decode("0004466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap().to_vec();
|
||||
assert!(outbound_peer.process_act_two(&act_two[..], &our_node_id, &secp_ctx).is_err());
|
||||
assert!(outbound_peer.process_act_two(&act_two[..], &&node_signer).is_err());
|
||||
}
|
||||
|
||||
{
|
||||
@ -618,7 +644,7 @@ mod tests {
|
||||
let mut outbound_peer = get_outbound_peer_for_initiator_test_vectors();
|
||||
|
||||
let act_two = hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730af").unwrap().to_vec();
|
||||
assert!(outbound_peer.process_act_two(&act_two[..], &our_node_id, &secp_ctx).is_err());
|
||||
assert!(outbound_peer.process_act_two(&act_two[..], &&node_signer).is_err());
|
||||
}
|
||||
}
|
||||
|
||||
@ -626,7 +652,8 @@ mod tests {
|
||||
fn noise_responder_test_vectors() {
|
||||
let our_node_id = SecretKey::from_slice(&hex::decode("2121212121212121212121212121212121212121212121212121212121212121").unwrap()[..]).unwrap();
|
||||
let our_ephemeral = SecretKey::from_slice(&hex::decode("2222222222222222222222222222222222222222222222222222222222222222").unwrap()[..]).unwrap();
|
||||
let secp_ctx = Secp256k1::signing_only();
|
||||
let secp_ctx = Secp256k1::new();
|
||||
let node_signer = TestNodeSigner::new(our_node_id);
|
||||
|
||||
{
|
||||
let _ = get_inbound_peer_for_test_vectors();
|
||||
@ -637,31 +664,31 @@ mod tests {
|
||||
}
|
||||
{
|
||||
// transport-responder act1 bad version test
|
||||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id, &secp_ctx);
|
||||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&&node_signer);
|
||||
|
||||
let act_one = hex::decode("01036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a").unwrap().to_vec();
|
||||
assert!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone(), &secp_ctx).is_err());
|
||||
assert!(inbound_peer.process_act_one_with_keys(&act_one[..], &&node_signer, our_ephemeral.clone(), &secp_ctx).is_err());
|
||||
}
|
||||
{
|
||||
// transport-responder act1 bad key serialization test
|
||||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id, &secp_ctx);
|
||||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&&node_signer);
|
||||
|
||||
let act_one =hex::decode("00046360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a").unwrap().to_vec();
|
||||
assert!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone(), &secp_ctx).is_err());
|
||||
assert!(inbound_peer.process_act_one_with_keys(&act_one[..], &&node_signer, our_ephemeral.clone(), &secp_ctx).is_err());
|
||||
}
|
||||
{
|
||||
// transport-responder act1 bad MAC test
|
||||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id, &secp_ctx);
|
||||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&&node_signer);
|
||||
|
||||
let act_one = hex::decode("00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6b").unwrap().to_vec();
|
||||
assert!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone(), &secp_ctx).is_err());
|
||||
assert!(inbound_peer.process_act_one_with_keys(&act_one[..], &&node_signer, our_ephemeral.clone(), &secp_ctx).is_err());
|
||||
}
|
||||
{
|
||||
// transport-responder act3 bad version test
|
||||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id, &secp_ctx);
|
||||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&&node_signer);
|
||||
|
||||
let act_one = hex::decode("00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a").unwrap().to_vec();
|
||||
assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone(), &secp_ctx).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
|
||||
assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &&node_signer, our_ephemeral.clone(), &secp_ctx).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
|
||||
|
||||
let act_three = hex::decode("01b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba").unwrap().to_vec();
|
||||
assert!(inbound_peer.process_act_three(&act_three[..]).is_err());
|
||||
@ -672,30 +699,30 @@ mod tests {
|
||||
}
|
||||
{
|
||||
// transport-responder act3 bad MAC for ciphertext test
|
||||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id, &secp_ctx);
|
||||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&&node_signer);
|
||||
|
||||
let act_one = hex::decode("00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a").unwrap().to_vec();
|
||||
assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone(), &secp_ctx).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
|
||||
assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &&node_signer, our_ephemeral.clone(), &secp_ctx).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
|
||||
|
||||
let act_three = hex::decode("00c9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba").unwrap().to_vec();
|
||||
assert!(inbound_peer.process_act_three(&act_three[..]).is_err());
|
||||
}
|
||||
{
|
||||
// transport-responder act3 bad rs test
|
||||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id, &secp_ctx);
|
||||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&&node_signer);
|
||||
|
||||
let act_one = hex::decode("00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a").unwrap().to_vec();
|
||||
assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone(), &secp_ctx).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
|
||||
assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &&node_signer, our_ephemeral.clone(), &secp_ctx).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
|
||||
|
||||
let act_three = hex::decode("00bfe3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa2235536ad09a8ee351870c2bb7f78b754a26c6cef79a98d25139c856d7efd252c2ae73c").unwrap().to_vec();
|
||||
assert!(inbound_peer.process_act_three(&act_three[..]).is_err());
|
||||
}
|
||||
{
|
||||
// transport-responder act3 bad MAC test
|
||||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id, &secp_ctx);
|
||||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&&node_signer);
|
||||
|
||||
let act_one = hex::decode("00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a").unwrap().to_vec();
|
||||
assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone(), &secp_ctx).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
|
||||
assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &&node_signer, our_ephemeral.clone(), &secp_ctx).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
|
||||
|
||||
let act_three = hex::decode("00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139bb").unwrap().to_vec();
|
||||
assert!(inbound_peer.process_act_three(&act_three[..]).is_err());
|
||||
@ -708,13 +735,13 @@ mod tests {
|
||||
// We use the same keys as the initiator and responder test vectors, so we copy those tests
|
||||
// here and use them to encrypt.
|
||||
let mut outbound_peer = get_outbound_peer_for_initiator_test_vectors();
|
||||
let secp_ctx = Secp256k1::signing_only();
|
||||
|
||||
{
|
||||
let our_node_id = SecretKey::from_slice(&hex::decode("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..]).unwrap();
|
||||
let node_signer = TestNodeSigner::new(our_node_id);
|
||||
|
||||
let act_two = hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap().to_vec();
|
||||
assert_eq!(outbound_peer.process_act_two(&act_two[..], &our_node_id, &secp_ctx).unwrap().0[..], hex::decode("00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba").unwrap()[..]);
|
||||
assert_eq!(outbound_peer.process_act_two(&act_two[..], &&node_signer).unwrap().0[..], hex::decode("00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba").unwrap()[..]);
|
||||
|
||||
match outbound_peer.noise_state {
|
||||
NoiseState::Finished { sk, sn, sck, rk, rn, rck } => {
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
use bitcoin::secp256k1::{self, Secp256k1, SecretKey, PublicKey};
|
||||
|
||||
use crate::chain::keysinterface::{KeysManager, NodeSigner, Recipient};
|
||||
use crate::ln::features::{InitFeatures, NodeFeatures};
|
||||
use crate::ln::msgs;
|
||||
use crate::ln::msgs::{ChannelMessageHandler, LightningError, NetAddress, OnionMessageHandler, RoutingMessageHandler};
|
||||
@ -28,7 +29,6 @@ use crate::ln::wire::Encode;
|
||||
use crate::onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, SimpleArcOnionMessenger, SimpleRefOnionMessenger};
|
||||
use crate::routing::gossip::{NetworkGraph, P2PGossipSync};
|
||||
use crate::util::atomic_counter::AtomicCounter;
|
||||
use crate::util::crypto::sign;
|
||||
use crate::util::events::{MessageSendEvent, MessageSendEventsProvider, OnionMessageProvider};
|
||||
use crate::util::logger::Logger;
|
||||
|
||||
@ -43,7 +43,6 @@ use core::convert::Infallible;
|
||||
#[cfg(feature = "std")] use std::error;
|
||||
|
||||
use bitcoin::hashes::sha256::Hash as Sha256;
|
||||
use bitcoin::hashes::sha256d::Hash as Sha256dHash;
|
||||
use bitcoin::hashes::sha256::HashEngine as Sha256Engine;
|
||||
use bitcoin::hashes::{HashEngine, Hash};
|
||||
|
||||
@ -491,7 +490,7 @@ impl Peer {
|
||||
/// issues such as overly long function definitions.
|
||||
///
|
||||
/// (C-not exported) as `Arc`s don't make sense in bindings.
|
||||
pub type SimpleArcPeerManager<SD, M, T, F, C, L> = PeerManager<SD, Arc<SimpleArcChannelManager<M, T, F, L>>, Arc<P2PGossipSync<Arc<NetworkGraph<Arc<L>>>, Arc<C>, Arc<L>>>, Arc<SimpleArcOnionMessenger<L>>, Arc<L>, IgnoringMessageHandler>;
|
||||
pub type SimpleArcPeerManager<SD, M, T, F, C, L> = PeerManager<SD, Arc<SimpleArcChannelManager<M, T, F, L>>, Arc<P2PGossipSync<Arc<NetworkGraph<Arc<L>>>, Arc<C>, Arc<L>>>, Arc<SimpleArcOnionMessenger<L>>, Arc<L>, IgnoringMessageHandler, Arc<KeysManager>>;
|
||||
|
||||
/// SimpleRefPeerManager is a type alias for a PeerManager reference, and is the reference
|
||||
/// counterpart to the SimpleArcPeerManager type alias. Use this type by default when you don't
|
||||
@ -501,7 +500,7 @@ pub type SimpleArcPeerManager<SD, M, T, F, C, L> = PeerManager<SD, Arc<SimpleArc
|
||||
/// helps with issues such as long function definitions.
|
||||
///
|
||||
/// (C-not exported) as general type aliases don't make sense in bindings.
|
||||
pub type SimpleRefPeerManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, SD, M, T, F, C, L> = PeerManager<SD, SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'm, M, T, F, L>, &'f P2PGossipSync<&'g NetworkGraph<&'f L>, &'h C, &'f L>, &'i SimpleRefOnionMessenger<'j, 'k, L>, &'f L, IgnoringMessageHandler>;
|
||||
pub type SimpleRefPeerManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, SD, M, T, F, C, L> = PeerManager<SD, SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'm, M, T, F, L>, &'f P2PGossipSync<&'g NetworkGraph<&'f L>, &'h C, &'f L>, &'i SimpleRefOnionMessenger<'j, 'k, L>, &'f L, IgnoringMessageHandler, &'c KeysManager>;
|
||||
|
||||
/// A PeerManager manages a set of peers, described by their [`SocketDescriptor`] and marshalls
|
||||
/// socket events into messages which it passes on to its [`MessageHandler`].
|
||||
@ -522,12 +521,13 @@ pub type SimpleRefPeerManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm
|
||||
/// you're using lightning-net-tokio.
|
||||
///
|
||||
/// [`read_event`]: PeerManager::read_event
|
||||
pub struct PeerManager<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CMH: Deref> where
|
||||
pub struct PeerManager<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CMH: Deref, NS: Deref> where
|
||||
CM::Target: ChannelMessageHandler,
|
||||
RM::Target: RoutingMessageHandler,
|
||||
OM::Target: OnionMessageHandler,
|
||||
L::Target: Logger,
|
||||
CMH::Target: CustomMessageHandler {
|
||||
CMH::Target: CustomMessageHandler,
|
||||
NS::Target: NodeSigner {
|
||||
message_handler: MessageHandler<CM, RM, OM>,
|
||||
/// Connection state for each connected peer - we have an outer read-write lock which is taken
|
||||
/// as read while we're doing processing for a peer and taken write when a peer is being added
|
||||
@ -557,12 +557,13 @@ pub struct PeerManager<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: D
|
||||
/// value increases strictly since we don't assume access to a time source.
|
||||
last_node_announcement_serial: AtomicU32,
|
||||
|
||||
our_node_secret: SecretKey,
|
||||
ephemeral_key_midstate: Sha256Engine,
|
||||
custom_message_handler: CMH,
|
||||
|
||||
peer_counter: AtomicCounter,
|
||||
|
||||
node_signer: NS,
|
||||
|
||||
logger: L,
|
||||
secp_ctx: Secp256k1<secp256k1::SignOnly>
|
||||
}
|
||||
@ -592,10 +593,11 @@ macro_rules! encode_msg {
|
||||
}}
|
||||
}
|
||||
|
||||
impl<Descriptor: SocketDescriptor, CM: Deref, OM: Deref, L: Deref> PeerManager<Descriptor, CM, IgnoringMessageHandler, OM, L, IgnoringMessageHandler> where
|
||||
impl<Descriptor: SocketDescriptor, CM: Deref, OM: Deref, L: Deref, NS: Deref> PeerManager<Descriptor, CM, IgnoringMessageHandler, OM, L, IgnoringMessageHandler, NS> where
|
||||
CM::Target: ChannelMessageHandler,
|
||||
OM::Target: OnionMessageHandler,
|
||||
L::Target: Logger {
|
||||
L::Target: Logger,
|
||||
NS::Target: NodeSigner {
|
||||
/// Constructs a new `PeerManager` with the given `ChannelMessageHandler` and
|
||||
/// `OnionMessageHandler`. No routing message handler is used and network graph messages are
|
||||
/// ignored.
|
||||
@ -609,18 +611,19 @@ impl<Descriptor: SocketDescriptor, CM: Deref, OM: Deref, L: Deref> PeerManager<D
|
||||
/// minute should suffice.
|
||||
///
|
||||
/// (C-not exported) as we can't export a PeerManager with a dummy route handler
|
||||
pub fn new_channel_only(channel_message_handler: CM, onion_message_handler: OM, our_node_secret: SecretKey, current_time: u32, ephemeral_random_data: &[u8; 32], logger: L) -> Self {
|
||||
pub fn new_channel_only(channel_message_handler: CM, onion_message_handler: OM, current_time: u32, ephemeral_random_data: &[u8; 32], logger: L, node_signer: NS) -> Self {
|
||||
Self::new(MessageHandler {
|
||||
chan_handler: channel_message_handler,
|
||||
route_handler: IgnoringMessageHandler{},
|
||||
onion_message_handler,
|
||||
}, our_node_secret, current_time, ephemeral_random_data, logger, IgnoringMessageHandler{})
|
||||
}, current_time, ephemeral_random_data, logger, IgnoringMessageHandler{}, node_signer)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Descriptor: SocketDescriptor, RM: Deref, L: Deref> PeerManager<Descriptor, ErroringMessageHandler, RM, IgnoringMessageHandler, L, IgnoringMessageHandler> where
|
||||
impl<Descriptor: SocketDescriptor, RM: Deref, L: Deref, NS: Deref> PeerManager<Descriptor, ErroringMessageHandler, RM, IgnoringMessageHandler, L, IgnoringMessageHandler, NS> where
|
||||
RM::Target: RoutingMessageHandler,
|
||||
L::Target: Logger {
|
||||
L::Target: Logger,
|
||||
NS::Target: NodeSigner {
|
||||
/// Constructs a new `PeerManager` with the given `RoutingMessageHandler`. No channel message
|
||||
/// handler or onion message handler is used and onion and channel messages will be ignored (or
|
||||
/// generate error messages). Note that some other lightning implementations time-out connections
|
||||
@ -635,12 +638,12 @@ impl<Descriptor: SocketDescriptor, RM: Deref, L: Deref> PeerManager<Descriptor,
|
||||
/// cryptographically secure random bytes.
|
||||
///
|
||||
/// (C-not exported) as we can't export a PeerManager with a dummy channel handler
|
||||
pub fn new_routing_only(routing_message_handler: RM, our_node_secret: SecretKey, current_time: u32, ephemeral_random_data: &[u8; 32], logger: L) -> Self {
|
||||
pub fn new_routing_only(routing_message_handler: RM, current_time: u32, ephemeral_random_data: &[u8; 32], logger: L, node_signer: NS) -> Self {
|
||||
Self::new(MessageHandler {
|
||||
chan_handler: ErroringMessageHandler::new(),
|
||||
route_handler: routing_message_handler,
|
||||
onion_message_handler: IgnoringMessageHandler{},
|
||||
}, our_node_secret, current_time, ephemeral_random_data, logger, IgnoringMessageHandler{})
|
||||
}, current_time, ephemeral_random_data, logger, IgnoringMessageHandler{}, node_signer)
|
||||
}
|
||||
}
|
||||
|
||||
@ -685,12 +688,14 @@ fn filter_addresses(ip_address: Option<NetAddress>) -> Option<NetAddress> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CMH: Deref> PeerManager<Descriptor, CM, RM, OM, L, CMH> where
|
||||
impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CMH: Deref, NS: Deref> PeerManager<Descriptor, CM, RM, OM, L, CMH, NS> where
|
||||
CM::Target: ChannelMessageHandler,
|
||||
RM::Target: RoutingMessageHandler,
|
||||
OM::Target: OnionMessageHandler,
|
||||
L::Target: Logger,
|
||||
CMH::Target: CustomMessageHandler {
|
||||
CMH::Target: CustomMessageHandler,
|
||||
NS::Target: NodeSigner
|
||||
{
|
||||
/// Constructs a new PeerManager with the given message handlers and node_id secret key
|
||||
/// ephemeral_random_data is used to derive per-connection ephemeral keys and must be
|
||||
/// cryptographically secure random bytes.
|
||||
@ -699,7 +704,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
|
||||
/// incremented irregularly internally. In general it is best to simply use the current UNIX
|
||||
/// timestamp, however if it is not available a persistent counter that increases once per
|
||||
/// minute should suffice.
|
||||
pub fn new(message_handler: MessageHandler<CM, RM, OM>, our_node_secret: SecretKey, current_time: u32, ephemeral_random_data: &[u8; 32], logger: L, custom_message_handler: CMH) -> Self {
|
||||
pub fn new(message_handler: MessageHandler<CM, RM, OM>, current_time: u32, ephemeral_random_data: &[u8; 32], logger: L, custom_message_handler: CMH, node_signer: NS) -> Self {
|
||||
let mut ephemeral_key_midstate = Sha256::engine();
|
||||
ephemeral_key_midstate.input(ephemeral_random_data);
|
||||
|
||||
@ -713,12 +718,12 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
|
||||
node_id_to_descriptor: Mutex::new(HashMap::new()),
|
||||
event_processing_lock: Mutex::new(()),
|
||||
blocked_event_processors: AtomicBool::new(false),
|
||||
our_node_secret,
|
||||
ephemeral_key_midstate,
|
||||
peer_counter: AtomicCounter::new(),
|
||||
last_node_announcement_serial: AtomicU32::new(current_time),
|
||||
logger,
|
||||
custom_message_handler,
|
||||
node_signer,
|
||||
secp_ctx,
|
||||
}
|
||||
}
|
||||
@ -810,7 +815,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
|
||||
///
|
||||
/// [`socket_disconnected()`]: PeerManager::socket_disconnected
|
||||
pub fn new_inbound_connection(&self, descriptor: Descriptor, remote_network_address: Option<NetAddress>) -> Result<(), PeerHandleError> {
|
||||
let peer_encryptor = PeerChannelEncryptor::new_inbound(&self.our_node_secret, &self.secp_ctx);
|
||||
let peer_encryptor = PeerChannelEncryptor::new_inbound(&self.node_signer);
|
||||
let pending_read_buffer = [0; 50].to_vec(); // Noise act one is 50 bytes
|
||||
|
||||
let mut peers = self.peers.write().unwrap();
|
||||
@ -1079,14 +1084,14 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
|
||||
NextNoiseStep::ActOne => {
|
||||
let act_two = try_potential_handleerror!(peer, peer.channel_encryptor
|
||||
.process_act_one_with_keys(&peer.pending_read_buffer[..],
|
||||
&self.our_node_secret, self.get_ephemeral_key(), &self.secp_ctx)).to_vec();
|
||||
&self.node_signer, self.get_ephemeral_key(), &self.secp_ctx)).to_vec();
|
||||
peer.pending_outbound_buffer.push_back(act_two);
|
||||
peer.pending_read_buffer = [0; 66].to_vec(); // act three is 66 bytes long
|
||||
},
|
||||
NextNoiseStep::ActTwo => {
|
||||
let (act_three, their_node_id) = try_potential_handleerror!(peer,
|
||||
peer.channel_encryptor.process_act_two(&peer.pending_read_buffer[..],
|
||||
&self.our_node_secret, &self.secp_ctx));
|
||||
&self.node_signer));
|
||||
peer.pending_outbound_buffer.push_back(act_three.to_vec());
|
||||
peer.pending_read_buffer = [0; 18].to_vec(); // Message length header is 18 bytes
|
||||
peer.pending_read_is_header = true;
|
||||
@ -2016,13 +2021,20 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
|
||||
let announcement = msgs::UnsignedNodeAnnouncement {
|
||||
features,
|
||||
timestamp: self.last_node_announcement_serial.fetch_add(1, Ordering::AcqRel),
|
||||
node_id: PublicKey::from_secret_key(&self.secp_ctx, &self.our_node_secret),
|
||||
node_id: self.node_signer.get_node_id(Recipient::Node).unwrap(),
|
||||
rgb, alias, addresses,
|
||||
excess_address_data: Vec::new(),
|
||||
excess_data: Vec::new(),
|
||||
};
|
||||
let msghash = hash_to_message!(&Sha256dHash::hash(&announcement.encode()[..])[..]);
|
||||
let node_announce_sig = sign(&self.secp_ctx, &msghash, &self.our_node_secret);
|
||||
let node_announce_sig = match self.node_signer.sign_gossip_message(
|
||||
msgs::UnsignedGossipMessage::NodeAnnouncement(&announcement)
|
||||
) {
|
||||
Ok(sig) => sig,
|
||||
Err(_) => {
|
||||
log_error!(self.logger, "Failed to generate signature for node_announcement");
|
||||
return;
|
||||
},
|
||||
};
|
||||
|
||||
let msg = msgs::NodeAnnouncement {
|
||||
signature: node_announce_sig,
|
||||
@ -2050,14 +2062,14 @@ fn is_gossip_msg(type_id: u16) -> bool {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::chain::keysinterface::{NodeSigner, Recipient};
|
||||
use crate::ln::peer_handler::{PeerManager, MessageHandler, SocketDescriptor, IgnoringMessageHandler, filter_addresses};
|
||||
use crate::ln::{msgs, wire};
|
||||
use crate::ln::msgs::NetAddress;
|
||||
use crate::util::events;
|
||||
use crate::util::test_utils;
|
||||
|
||||
use bitcoin::secp256k1::Secp256k1;
|
||||
use bitcoin::secp256k1::{SecretKey, PublicKey};
|
||||
use bitcoin::secp256k1::SecretKey;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::sync::{Arc, Mutex};
|
||||
@ -2093,16 +2105,19 @@ mod tests {
|
||||
chan_handler: test_utils::TestChannelMessageHandler,
|
||||
routing_handler: test_utils::TestRoutingMessageHandler,
|
||||
logger: test_utils::TestLogger,
|
||||
node_signer: test_utils::TestNodeSigner,
|
||||
}
|
||||
|
||||
fn create_peermgr_cfgs(peer_count: usize) -> Vec<PeerManagerCfg> {
|
||||
let mut cfgs = Vec::new();
|
||||
for _ in 0..peer_count {
|
||||
for i in 0..peer_count {
|
||||
let node_secret = SecretKey::from_slice(&[42 + i as u8; 32]).unwrap();
|
||||
cfgs.push(
|
||||
PeerManagerCfg{
|
||||
chan_handler: test_utils::TestChannelMessageHandler::new(),
|
||||
logger: test_utils::TestLogger::new(),
|
||||
routing_handler: test_utils::TestRoutingMessageHandler::new(),
|
||||
node_signer: test_utils::TestNodeSigner::new(node_secret),
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -2110,22 +2125,20 @@ mod tests {
|
||||
cfgs
|
||||
}
|
||||
|
||||
fn create_network<'a>(peer_count: usize, cfgs: &'a Vec<PeerManagerCfg>) -> Vec<PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, IgnoringMessageHandler, &'a test_utils::TestLogger, IgnoringMessageHandler>> {
|
||||
fn create_network<'a>(peer_count: usize, cfgs: &'a Vec<PeerManagerCfg>) -> Vec<PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, IgnoringMessageHandler, &'a test_utils::TestLogger, IgnoringMessageHandler, &'a test_utils::TestNodeSigner>> {
|
||||
let mut peers = Vec::new();
|
||||
for i in 0..peer_count {
|
||||
let node_secret = SecretKey::from_slice(&[42 + i as u8; 32]).unwrap();
|
||||
let ephemeral_bytes = [i as u8; 32];
|
||||
let msg_handler = MessageHandler { chan_handler: &cfgs[i].chan_handler, route_handler: &cfgs[i].routing_handler, onion_message_handler: IgnoringMessageHandler {} };
|
||||
let peer = PeerManager::new(msg_handler, node_secret, 0, &ephemeral_bytes, &cfgs[i].logger, IgnoringMessageHandler {});
|
||||
let peer = PeerManager::new(msg_handler, 0, &ephemeral_bytes, &cfgs[i].logger, IgnoringMessageHandler {}, &cfgs[i].node_signer);
|
||||
peers.push(peer);
|
||||
}
|
||||
|
||||
peers
|
||||
}
|
||||
|
||||
fn establish_connection<'a>(peer_a: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, IgnoringMessageHandler, &'a test_utils::TestLogger, IgnoringMessageHandler>, peer_b: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, IgnoringMessageHandler, &'a test_utils::TestLogger, IgnoringMessageHandler>) -> (FileDescriptor, FileDescriptor) {
|
||||
let secp_ctx = Secp256k1::new();
|
||||
let a_id = PublicKey::from_secret_key(&secp_ctx, &peer_a.our_node_secret);
|
||||
fn establish_connection<'a>(peer_a: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, IgnoringMessageHandler, &'a test_utils::TestLogger, IgnoringMessageHandler, &'a test_utils::TestNodeSigner>, peer_b: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, IgnoringMessageHandler, &'a test_utils::TestLogger, IgnoringMessageHandler, &'a test_utils::TestNodeSigner>) -> (FileDescriptor, FileDescriptor) {
|
||||
let a_id = peer_a.node_signer.get_node_id(Recipient::Node).unwrap();
|
||||
let mut fd_a = FileDescriptor { fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())) };
|
||||
let mut fd_b = FileDescriptor { fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())) };
|
||||
let initial_data = peer_b.new_outbound_connection(a_id, fd_b.clone(), None).unwrap();
|
||||
@ -2157,8 +2170,7 @@ mod tests {
|
||||
establish_connection(&peers[0], &peers[1]);
|
||||
assert_eq!(peers[0].peers.read().unwrap().len(), 1);
|
||||
|
||||
let secp_ctx = Secp256k1::new();
|
||||
let their_id = PublicKey::from_secret_key(&secp_ctx, &peers[1].our_node_secret);
|
||||
let their_id = peers[1].node_signer.get_node_id(Recipient::Node).unwrap();
|
||||
|
||||
chan_handler.pending_events.lock().unwrap().push(events::MessageSendEvent::HandleError {
|
||||
node_id: their_id,
|
||||
@ -2182,8 +2194,7 @@ mod tests {
|
||||
let (fd_a, mut fd_b) = establish_connection(&peers[0], &peers[1]);
|
||||
assert_eq!(peers[0].peers.read().unwrap().len(), 1);
|
||||
|
||||
let secp_ctx = Secp256k1::new();
|
||||
let their_id = PublicKey::from_secret_key(&secp_ctx, &peers[1].our_node_secret);
|
||||
let their_id = peers[1].node_signer.get_node_id(Recipient::Node).unwrap();
|
||||
|
||||
let msg = msgs::Shutdown { channel_id: [42; 32], scriptpubkey: bitcoin::Script::new() };
|
||||
a_chan_handler.pending_events.lock().unwrap().push(events::MessageSendEvent::SendShutdown {
|
||||
@ -2283,8 +2294,7 @@ mod tests {
|
||||
cfgs[1].routing_handler.request_full_sync.store(true, Ordering::Release);
|
||||
let peers = create_network(2, &cfgs);
|
||||
|
||||
let secp_ctx = Secp256k1::new();
|
||||
let a_id = PublicKey::from_secret_key(&secp_ctx, &peers[0].our_node_secret);
|
||||
let a_id = peers[0].node_signer.get_node_id(Recipient::Node).unwrap();
|
||||
let mut fd_a = FileDescriptor { fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())) };
|
||||
let mut fd_b = FileDescriptor { fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())) };
|
||||
let initial_data = peers[1].new_outbound_connection(a_id, fd_b.clone(), None).unwrap();
|
||||
|
@ -12,7 +12,7 @@
|
||||
//! LSP).
|
||||
|
||||
use crate::chain::ChannelMonitorUpdateStatus;
|
||||
use crate::chain::keysinterface::{Recipient, NodeSigner};
|
||||
use crate::chain::keysinterface::NodeSigner;
|
||||
use crate::ln::channelmanager::{ChannelManager, MIN_CLTV_EXPIRY_DELTA, PaymentId};
|
||||
use crate::routing::gossip::RoutingFees;
|
||||
use crate::routing::router::{PaymentParameters, RouteHint, RouteHintHop};
|
||||
@ -31,10 +31,7 @@ use core::default::Default;
|
||||
use crate::ln::functional_test_utils::*;
|
||||
|
||||
use bitcoin::blockdata::constants::genesis_block;
|
||||
use bitcoin::hashes::Hash;
|
||||
use bitcoin::hashes::sha256d::Hash as Sha256dHash;
|
||||
use bitcoin::network::constants::Network;
|
||||
use bitcoin::secp256k1::Secp256k1;
|
||||
|
||||
#[test]
|
||||
fn test_priv_forwarding_rejection() {
|
||||
@ -493,8 +490,7 @@ fn test_scid_alias_returned() {
|
||||
fee_proportional_millionths: last_hop[0].counterparty.forwarding_info.as_ref().unwrap().fee_proportional_millionths,
|
||||
excess_data: Vec::new(),
|
||||
};
|
||||
let msg_hash = Sha256dHash::hash(&contents.encode()[..]);
|
||||
let signature = Secp256k1::new().sign_ecdsa(&hash_to_message!(&msg_hash[..]), &nodes[1].keys_manager.get_node_secret(Recipient::Node).unwrap());
|
||||
let signature = nodes[1].keys_manager.sign_gossip_message(msgs::UnsignedGossipMessage::ChannelUpdate(&contents)).unwrap();
|
||||
let msg = msgs::ChannelUpdate { signature, contents };
|
||||
|
||||
let mut err_data = Vec::new();
|
||||
|
@ -30,8 +30,7 @@ struct MessengerNode {
|
||||
|
||||
impl MessengerNode {
|
||||
fn get_node_pk(&self) -> PublicKey {
|
||||
let secp_ctx = Secp256k1::new();
|
||||
PublicKey::from_secret_key(&secp_ctx, &self.keys_manager.get_node_secret(Recipient::Node).unwrap())
|
||||
self.keys_manager.get_node_id(Recipient::Node).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,9 +223,10 @@ impl BaseSign for EnforcingSigner {
|
||||
self.inner.sign_holder_anchor_input(anchor_tx, input, secp_ctx)
|
||||
}
|
||||
|
||||
fn sign_channel_announcement(&self, msg: &msgs::UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>)
|
||||
-> Result<(Signature, Signature), ()> {
|
||||
self.inner.sign_channel_announcement(msg, secp_ctx)
|
||||
fn sign_channel_announcement_with_funding_key(
|
||||
&self, msg: &msgs::UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>
|
||||
) -> Result<Signature, ()> {
|
||||
self.inner.sign_channel_announcement_with_funding_key(msg, secp_ctx)
|
||||
}
|
||||
|
||||
fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters) {
|
||||
|
@ -51,7 +51,7 @@ 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, EntropySource, NodeSigner, SignerProvider};
|
||||
use crate::chain::keysinterface::{InMemorySigner, Recipient, EntropySource, NodeSigner, SignerProvider};
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
@ -107,17 +107,6 @@ pub struct OnlyReadsKeysInterface {}
|
||||
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 sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result<RecoverableSignature, ()> { unreachable!(); }
|
||||
}
|
||||
|
||||
impl SignerProvider for OnlyReadsKeysInterface {
|
||||
type Signer = EnforcingSigner;
|
||||
|
||||
@ -126,8 +115,7 @@ impl SignerProvider for OnlyReadsKeysInterface {
|
||||
fn derive_channel_signer(&self, _channel_value_satoshis: u64, _channel_keys_id: [u8; 32]) -> Self::Signer { unreachable!(); }
|
||||
|
||||
fn read_chan_signer(&self, mut reader: &[u8]) -> Result<Self::Signer, msgs::DecodeError> {
|
||||
let dummy_sk = SecretKey::from_slice(&[42; 32]).unwrap();
|
||||
let inner: InMemorySigner = ReadableArgs::read(&mut reader, dummy_sk)?;
|
||||
let inner: InMemorySigner = Readable::read(&mut reader)?;
|
||||
let state = Arc::new(Mutex::new(EnforcementState::new()));
|
||||
|
||||
Ok(EnforcingSigner::new_with_revoked(
|
||||
@ -632,6 +620,49 @@ impl Logger for TestLogger {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TestNodeSigner {
|
||||
node_secret: SecretKey,
|
||||
}
|
||||
|
||||
impl TestNodeSigner {
|
||||
pub fn new(node_secret: SecretKey) -> Self {
|
||||
Self { node_secret }
|
||||
}
|
||||
}
|
||||
|
||||
impl NodeSigner for TestNodeSigner {
|
||||
fn get_inbound_payment_key_material(&self) -> crate::chain::keysinterface::KeyMaterial {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
|
||||
let node_secret = match recipient {
|
||||
Recipient::Node => Ok(&self.node_secret),
|
||||
Recipient::PhantomNode => Err(())
|
||||
}?;
|
||||
Ok(PublicKey::from_secret_key(&Secp256k1::signing_only(), node_secret))
|
||||
}
|
||||
|
||||
fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&bitcoin::secp256k1::Scalar>) -> Result<SharedSecret, ()> {
|
||||
let mut node_secret = match recipient {
|
||||
Recipient::Node => Ok(self.node_secret.clone()),
|
||||
Recipient::PhantomNode => Err(())
|
||||
}?;
|
||||
if let Some(tweak) = tweak {
|
||||
node_secret = node_secret.mul_tweak(tweak).map_err(|_| ())?;
|
||||
}
|
||||
Ok(SharedSecret::new(other_key, &node_secret))
|
||||
}
|
||||
|
||||
fn sign_invoice(&self, _: &[u8], _: &[bitcoin::bech32::u5], _: Recipient) -> Result<bitcoin::secp256k1::ecdsa::RecoverableSignature, ()> {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn sign_gossip_message(&self, _msg: msgs::UnsignedGossipMessage) -> Result<Signature, ()> {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TestKeysInterface {
|
||||
pub backing: keysinterface::PhantomKeysManager,
|
||||
pub override_random_bytes: Mutex<Option<[u8; 32]>>,
|
||||
@ -651,10 +682,6 @@ impl EntropySource for TestKeysInterface {
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
@ -670,6 +697,10 @@ impl NodeSigner 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 sign_gossip_message(&self, msg: msgs::UnsignedGossipMessage) -> Result<Signature, ()> {
|
||||
self.backing.sign_gossip_message(msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl SignerProvider for TestKeysInterface {
|
||||
@ -688,7 +719,7 @@ impl SignerProvider for TestKeysInterface {
|
||||
fn read_chan_signer(&self, buffer: &[u8]) -> Result<Self::Signer, msgs::DecodeError> {
|
||||
let mut reader = io::Cursor::new(buffer);
|
||||
|
||||
let inner: InMemorySigner = ReadableArgs::read(&mut reader, self.get_node_secret(Recipient::Node).unwrap())?;
|
||||
let inner: InMemorySigner = Readable::read(&mut reader)?;
|
||||
let state = self.make_enforcement_state_cell(inner.commitment_seed);
|
||||
|
||||
Ok(EnforcingSigner::new_with_revoked(
|
||||
|
Loading…
Reference in New Issue
Block a user