use bitcoin::{hashes::Hash, Transaction, Txid};
use dlc_messages::channel::{AcceptChannel, SignChannel};
use secp256k1_zkp::PublicKey;
use crate::{ChannelId, ContractId};
use self::{
accepted_channel::AcceptedChannel, offered_channel::OfferedChannel,
signed_channel::SignedChannel,
};
pub mod accepted_channel;
pub mod offered_channel;
pub mod party_points;
pub mod ser;
pub mod signed_channel;
mod utils;
#[derive(Clone)]
#[allow(clippy::large_enum_variant)]
pub enum Channel {
Offered(OfferedChannel),
Accepted(AcceptedChannel),
Signed(SignedChannel),
FailedAccept(FailedAccept),
FailedSign(FailedSign),
Cancelled(OfferedChannel),
Closing(ClosingChannel),
Closed(ClosedChannel),
CounterClosed(ClosedChannel),
ClosedPunished(ClosedPunishedChannel),
CollaborativelyClosed(ClosedChannel),
}
impl std::fmt::Debug for Channel {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let state = match self {
Channel::Offered(_) => "offered",
Channel::Accepted(_) => "accepted",
Channel::Signed(_) => "signed",
Channel::FailedAccept(_) => "failed accept",
Channel::FailedSign(_) => "failed sign",
Channel::Cancelled(_) => "cancelled",
Channel::Closing(_) => "closing",
Channel::Closed(_) => "closed",
Channel::CounterClosed(_) => "counter closed",
Channel::ClosedPunished(_) => "closed punished",
Channel::CollaborativelyClosed(_) => "collaboratively closed",
};
f.debug_struct("Contract").field("state", &state).finish()
}
}
impl Channel {
pub fn get_counter_party_id(&self) -> PublicKey {
match self {
Channel::Offered(o) => o.counter_party,
Channel::Accepted(a) => a.counter_party,
Channel::Signed(s) => s.counter_party,
Channel::FailedAccept(f) => f.counter_party,
Channel::FailedSign(f) => f.counter_party,
Channel::Cancelled(o) => o.counter_party,
Channel::Closing(c) => c.counter_party,
Channel::Closed(c) | Channel::CounterClosed(c) | Channel::CollaborativelyClosed(c) => {
c.counter_party
}
Channel::ClosedPunished(c) => c.counter_party,
}
}
}
#[derive(Clone)]
pub struct FailedAccept {
pub counter_party: PublicKey,
pub temporary_channel_id: ChannelId,
pub error_message: String,
pub accept_message: AcceptChannel,
}
#[derive(Clone)]
pub struct FailedSign {
pub counter_party: PublicKey,
pub channel_id: ChannelId,
pub error_message: String,
pub sign_message: SignChannel,
}
#[derive(Clone)]
pub struct ClosingChannel {
pub counter_party: PublicKey,
pub temporary_channel_id: ChannelId,
pub channel_id: ChannelId,
pub rollback_state: Option<SignedChannel>,
pub buffer_transaction: Transaction,
pub contract_id: ContractId,
pub is_closer: bool,
}
#[derive(Clone)]
pub struct ClosedChannel {
pub counter_party: PublicKey,
pub temporary_channel_id: ChannelId,
pub channel_id: ChannelId,
}
#[derive(Clone)]
pub struct ClosedPunishedChannel {
pub counter_party: PublicKey,
pub temporary_channel_id: ChannelId,
pub channel_id: ChannelId,
pub punish_txid: Txid,
}
impl Channel {
pub fn get_temporary_id(&self) -> ChannelId {
match self {
Channel::Offered(o) => o.temporary_channel_id,
Channel::Accepted(a) => a.temporary_channel_id,
Channel::Signed(s) => s.temporary_channel_id,
Channel::FailedAccept(f) => f.temporary_channel_id,
Channel::Closed(c) | Channel::CounterClosed(c) | Channel::CollaborativelyClosed(c) => {
c.temporary_channel_id
}
Channel::ClosedPunished(c) => c.temporary_channel_id,
_ => unimplemented!(),
}
}
pub fn get_id(&self) -> ChannelId {
match self {
Channel::Offered(o) => o.temporary_channel_id,
Channel::Accepted(a) => a.channel_id,
Channel::Signed(s) => s.channel_id,
Channel::FailedAccept(f) => f.temporary_channel_id,
Channel::FailedSign(f) => f.channel_id,
Channel::Closing(c) => c.channel_id,
Channel::Closed(c) | Channel::CounterClosed(c) | Channel::CollaborativelyClosed(c) => {
c.channel_id
}
Channel::ClosedPunished(c) => c.channel_id,
Channel::Cancelled(c) => c.temporary_channel_id,
}
}
pub fn get_contract_id(&self) -> Option<ContractId> {
match self {
Channel::Offered(o) => Some(o.offered_contract_id),
Channel::Accepted(a) => Some(a.accepted_contract_id),
Channel::Signed(s) => s.get_contract_id(),
Channel::FailedAccept(_) => None,
Channel::FailedSign(_) => None,
_ => None,
}
}
}
pub fn generate_temporary_contract_id(
channel_id: ChannelId,
channel_update_idx: u64,
) -> ContractId {
let mut data = Vec::with_capacity(65);
data.extend_from_slice(&channel_id);
data.extend_from_slice(&channel_update_idx.to_be_bytes());
bitcoin::hashes::sha256::Hash::hash(&data).to_byte_array()
}