use std::str::FromStr;
use secp256k1::{ecdsa, Secp256k1, Signing};
use crate::inet::PartialSocketAddr;
use crate::{AddrParseError, InetSocketAddr};
#[derive(
Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display, Error,
From
)]
#[display(doc_comments)]
#[from(secp256k1::Error)]
pub struct NodeIdInvalidPubkey;
#[derive(Debug, Display, Error, From)]
#[display(doc_comments)]
pub enum NodeAddrParseError {
#[from(NodeIdInvalidPubkey)]
InvalidId,
#[from]
#[display(inner)]
InvalidAddr(AddrParseError),
}
#[derive(
Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display, From
)]
#[cfg_attr(feature = "strict_encoding", derive(StrictEncode, StrictDecode))]
#[cfg_attr(
feature = "lightning_encoding",
derive(LightningEncode, LightningDecode)
)]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate", transparent)
)]
#[display(inner)]
pub struct NodeId(secp256k1::PublicKey);
impl NodeId {
#[inline]
pub fn public_key(self) -> secp256k1::PublicKey { self.0 }
}
impl FromStr for NodeId {
type Err = NodeIdInvalidPubkey;
fn from_str(s: &str) -> Result<Self, Self::Err> { Ok(NodeId(s.parse()?)) }
}
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display)]
#[cfg_attr(feature = "strict_encoding", derive(StrictEncode, StrictDecode))]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate")
)]
#[display("{id}@{addr}")]
pub struct NodeAddr {
pub id: NodeId,
pub addr: InetSocketAddr,
}
impl NodeAddr {
#[inline]
pub fn new(id: NodeId, addr: impl Into<InetSocketAddr>) -> NodeAddr {
NodeAddr {
id,
addr: addr.into(),
}
}
#[inline]
pub fn public_key(self) -> secp256k1::PublicKey { self.id.public_key() }
}
impl FromStr for NodeAddr {
type Err = NodeAddrParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut split = s.split('@');
match (split.next(), split.next(), split.next()) {
(Some(id), Some(addr), None) => Ok(NodeAddr {
id: id.parse()?,
addr: addr.parse()?,
}),
_ => Err(AddrParseError::WrongAddrFormat(s.to_owned()).into()),
}
}
}
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display)]
#[cfg_attr(feature = "strict_encoding", derive(StrictEncode, StrictDecode))]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate")
)]
#[display("{id}@{addr}")]
pub struct PartialNodeAddr {
pub id: NodeId,
pub addr: PartialSocketAddr,
}
impl PartialNodeAddr {
#[inline]
pub fn new(id: NodeId, addr: PartialSocketAddr) -> PartialNodeAddr {
PartialNodeAddr { id, addr }
}
#[inline]
pub fn node_addr(self, default_port: u16) -> NodeAddr {
NodeAddr {
id: self.id,
addr: self.addr.inet_socket(default_port),
}
}
}
impl FromStr for PartialNodeAddr {
type Err = NodeAddrParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut split = s.split('@');
match (split.next(), split.next(), split.next()) {
(Some(id), Some(addr), None) => Ok(PartialNodeAddr {
id: id.parse()?,
addr: addr.parse()?,
}),
_ => Err(AddrParseError::WrongAddrFormat(s.to_owned()).into()),
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)]
#[display("{id}")]
pub struct LocalNode {
id: NodeId,
private_key: secp256k1::SecretKey,
}
impl LocalNode {
#[cfg(feature = "keygen")]
pub fn new<C: Signing>(secp: &Secp256k1<C>) -> Self {
use secp256k1::rand::thread_rng;
let mut rng = thread_rng();
let private_key = secp256k1::SecretKey::new(&mut rng);
let public_key =
secp256k1::PublicKey::from_secret_key(secp, &private_key);
Self {
private_key,
id: NodeId::from(public_key),
}
}
#[inline]
pub fn with<C: Signing>(
secp: &Secp256k1<C>,
private_key: secp256k1::SecretKey,
) -> Self {
Self {
private_key,
id: secp256k1::PublicKey::from_secret_key(secp, &private_key)
.into(),
}
}
#[inline]
pub fn node_id(&self) -> NodeId { self.id }
#[inline]
pub fn private_key(&self) -> secp256k1::SecretKey { self.private_key }
#[inline]
pub fn sign<C: Signing>(
&self,
secp: &Secp256k1<C>,
message: &secp256k1::Message,
) -> ecdsa::Signature {
secp.sign_ecdsa(message, &self.private_key)
}
}