use std::collections::BTreeMap;
use std::convert::TryFrom;
use std::fmt::Debug;
use internet2::presentation::sphinx::Hop;
use lnp2p::bolt::Messages;
use lnpbp::chain::AssetId;
use p2p::bolt::PaymentOnion;
use strict_encoding::{
self, strict_deserialize, strict_serialize, StrictDecode, StrictEncode,
};
use super::{AnchorOutputs, BoltChannel, ChannelState, Error, Htlc};
use crate::channel::shared_ext::Bip96;
use crate::channel::tx_graph::TxRole;
use crate::channel::{self, Channel};
use crate::{extension, ChannelExtension};
pub type AssetsBalance = BTreeMap<AssetId, u64>;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)]
#[derive(StrictEncode, StrictDecode)]
#[display(Debug)]
pub enum BoltExt {
Channel = 0,
Bolt3 = 1,
Htlc = 2,
ShutdownScript = 10,
AnchorOutputs = 11,
Policy = 100,
Bip96 = 1000,
}
impl Default for BoltExt {
fn default() -> Self {
BoltExt::Channel
}
}
impl From<BoltExt> for u16 {
fn from(id: BoltExt) -> Self {
let mut buf = [0u8; 2];
buf.copy_from_slice(
&strict_serialize(&id)
.expect("Enum in-memory strict encoding can't fail"),
);
u16::from_be_bytes(buf)
}
}
impl TryFrom<u16> for BoltExt {
type Error = strict_encoding::Error;
fn try_from(value: u16) -> Result<Self, Self::Error> {
strict_deserialize(value.to_be_bytes())
}
}
impl extension::Nomenclature for BoltExt {
type State = ChannelState;
type Error = Error;
type PeerMessage = lnp2p::bolt::Messages;
type UpdateMessage = ();
type UpdateRequest = UpdateReq;
}
impl channel::Nomenclature for BoltExt {
type Constructor = BoltChannel;
#[inline]
fn default_extenders() -> Vec<Box<dyn ChannelExtension<Self>>> {
vec![Htlc::new()]
}
#[inline]
fn default_modifiers() -> Vec<Box<dyn ChannelExtension<Self>>> {
vec![Bip96::new()]
}
fn update_from_peer(
channel: &mut Channel<Self>,
message: &Messages,
) -> Result<(), Error> {
#[allow(clippy::single_match)] match message {
Messages::OpenChannel(open_channel) => {
if open_channel.has_anchor_outputs() {
channel.add_extender(AnchorOutputs::new())
}
}
_ => {}
}
Ok(())
}
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub enum UpdateReq {
PayBolt(Vec<Hop<PaymentOnion>>),
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)]
#[derive(StrictEncode, StrictDecode)]
#[display(Debug)]
pub enum TxType {
HtlcSuccess,
HtlcTimeout,
Unknown(u16),
}
impl From<TxType> for u16 {
fn from(ty: TxType) -> Self {
match ty {
TxType::HtlcSuccess => 0x0,
TxType::HtlcTimeout => 0x1,
TxType::Unknown(x) => x,
}
}
}
impl From<u16> for TxType {
fn from(ty: u16) -> Self {
match ty {
0x00 => TxType::HtlcSuccess,
0x01 => TxType::HtlcTimeout,
x => TxType::Unknown(x),
}
}
}
impl TxRole for TxType {}
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate")
)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)]
#[derive(StrictEncode, StrictDecode)]
#[repr(u8)]
pub enum Lifecycle {
#[display("INIT")]
Initial,
#[display("PROPOSED")]
Proposed,
#[display("ACCEPTED")]
Accepted,
#[display("SIGNING")]
Signing,
#[display("FUNDING")]
Funding,
#[display("SIGNED")]
Signed,
#[display("FUNDED")]
Funded,
#[display("LOCKED")]
Locked,
#[display("ACTIVE")]
Active,
#[display("REESTABLISHING")]
Reestablishing,
#[display("SHUTDOWN")]
Shutdown,
#[display("CLOSING-{round}")]
Closing { round: usize },
#[display("ABORTING")]
Aborting,
#[display("PENALIZE")]
Penalize,
#[display("CLOSED")]
Closed,
}
impl Default for Lifecycle {
fn default() -> Self {
Lifecycle::Initial
}
}