use bitcoin::{Amount, ScriptBuf};
use ddk_dlc::Error;
use lightning::ln::msgs::DecodeError;
use lightning::util::ser::{Readable, Writeable, Writer};
use secp256k1_zkp::{
ecdsa::Signature, EcdsaAdaptorSignature, PublicKey, Secp256k1, SecretKey, Verification,
};
use crate::FundingSignatures;
use crate::{
contract_msgs::ContractInfo,
ser_impls::{read_ecdsa_adaptor_signature, write_ecdsa_adaptor_signature},
types::*,
CetAdaptorSignatures, FundingInput, NegotiationFields,
};
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(
feature = "use-serde",
derive(serde::Serialize, serde::Deserialize),
serde(rename_all = "camelCase")
)]
pub struct OfferChannel {
pub protocol_version: u32,
pub contract_flags: u8,
#[cfg_attr(
feature = "use-serde",
serde(
serialize_with = "crate::serde_utils::serialize_hex",
deserialize_with = "crate::serde_utils::deserialize_hex_array"
)
)]
pub chain_hash: [u8; 32],
pub temporary_contract_id: [u8; 32],
pub temporary_channel_id: [u8; 32],
pub contract_info: ContractInfo,
pub funding_pubkey: PublicKey,
pub revocation_basepoint: PublicKey,
pub publish_basepoint: PublicKey,
pub own_basepoint: PublicKey,
pub first_per_update_point: PublicKey,
pub payout_spk: ScriptBuf,
pub payout_serial_id: u64,
pub offer_collateral: Amount,
pub funding_inputs: Vec<FundingInput>,
pub change_spk: ScriptBuf,
pub change_serial_id: u64,
pub fund_output_serial_id: u64,
pub fee_rate_per_vb: u64,
pub cet_locktime: u32,
pub refund_locktime: u32,
pub cet_nsequence: u32,
}
impl_dlc_writeable!(OfferChannel, OFFER_CHANNEL_TYPE, {
(protocol_version, writeable),
(contract_flags, writeable),
(chain_hash, writeable),
(temporary_contract_id, writeable),
(temporary_channel_id, writeable),
(contract_info, writeable),
(funding_pubkey, writeable),
(revocation_basepoint, writeable),
(publish_basepoint, writeable),
(own_basepoint, writeable),
(first_per_update_point, writeable),
(payout_spk, writeable),
(payout_serial_id, writeable),
(offer_collateral, writeable),
(funding_inputs, vec),
(change_spk, writeable),
(change_serial_id, writeable),
(fund_output_serial_id, writeable),
(fee_rate_per_vb, writeable),
(cet_locktime, writeable),
(refund_locktime, writeable),
(cet_nsequence, writeable)
});
impl OfferChannel {
pub fn validate<C: Verification>(
&self,
secp: &Secp256k1<C>,
min_timeout_interval: u32,
max_timeout_interval: u32,
min_cet_nsequence: u32,
max_cet_nsequence: u32,
) -> Result<(), Error> {
let closest_maturity_date = self.contract_info.get_closest_maturity_date();
let valid_dates = self.cet_locktime <= closest_maturity_date
&& closest_maturity_date + min_timeout_interval <= self.refund_locktime
&& self.refund_locktime <= closest_maturity_date + max_timeout_interval
&& self.cet_nsequence >= min_cet_nsequence
&& self.cet_nsequence <= max_cet_nsequence;
if !valid_dates {
return Err(Error::InvalidArgument(
"Locktime is less than closest maturity date".to_string(),
));
}
match &self.contract_info {
ContractInfo::SingleContractInfo(s) => s.contract_info.oracle_info.validate(secp)?,
ContractInfo::DisjointContractInfo(d) => {
for c in &d.contract_infos {
c.oracle_info.validate(secp)?;
}
}
}
Ok(())
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "use-serde",
derive(serde::Serialize, serde::Deserialize),
serde(rename_all = "camelCase")
)]
pub struct AcceptChannel {
#[cfg_attr(
feature = "use-serde",
serde(
serialize_with = "crate::serde_utils::serialize_hex",
deserialize_with = "crate::serde_utils::deserialize_hex_array"
)
)]
pub temporary_channel_id: [u8; 32],
pub accept_collateral: Amount,
pub funding_pubkey: PublicKey,
pub revocation_basepoint: PublicKey,
pub publish_basepoint: PublicKey,
pub own_basepoint: PublicKey,
pub first_per_update_point: PublicKey,
pub payout_spk: ScriptBuf,
pub payout_serial_id: u64,
pub funding_inputs: Vec<FundingInput>,
pub change_spk: ScriptBuf,
pub change_serial_id: u64,
pub cet_adaptor_signatures: CetAdaptorSignatures,
pub buffer_adaptor_signature: EcdsaAdaptorSignature,
pub refund_signature: Signature,
pub negotiation_fields: Option<NegotiationFields>,
}
impl_dlc_writeable!(AcceptChannel, ACCEPT_CHANNEL_TYPE, {
(temporary_channel_id, writeable),
(accept_collateral, writeable),
(funding_pubkey, writeable),
(revocation_basepoint, writeable),
(publish_basepoint, writeable),
(own_basepoint, writeable),
(first_per_update_point, writeable),
(payout_spk, writeable),
(payout_serial_id, writeable),
(funding_inputs, vec),
(change_spk, writeable),
(change_serial_id, writeable),
(cet_adaptor_signatures, writeable),
(buffer_adaptor_signature, {cb_writeable, write_ecdsa_adaptor_signature, read_ecdsa_adaptor_signature}),
(refund_signature, writeable),
(negotiation_fields, option)
});
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "use-serde",
derive(serde::Serialize, serde::Deserialize),
serde(rename_all = "camelCase")
)]
pub struct SignChannel {
#[cfg_attr(
feature = "use-serde",
serde(
serialize_with = "crate::serde_utils::serialize_hex",
deserialize_with = "crate::serde_utils::deserialize_hex_array"
)
)]
pub channel_id: [u8; 32],
pub cet_adaptor_signatures: CetAdaptorSignatures,
pub buffer_adaptor_signature: EcdsaAdaptorSignature,
pub refund_signature: Signature,
pub funding_signatures: FundingSignatures,
}
impl_dlc_writeable!(SignChannel, SIGN_CHANNEL_TYPE, {
(channel_id, writeable),
(cet_adaptor_signatures, writeable),
(buffer_adaptor_signature, {cb_writeable, write_ecdsa_adaptor_signature, read_ecdsa_adaptor_signature}),
(refund_signature, writeable),
(funding_signatures, writeable)
});
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "use-serde",
derive(serde::Serialize, serde::Deserialize),
serde(rename_all = "camelCase")
)]
pub struct SettleOffer {
#[cfg_attr(
feature = "use-serde",
serde(
serialize_with = "crate::serde_utils::serialize_hex",
deserialize_with = "crate::serde_utils::deserialize_hex_array"
)
)]
pub channel_id: [u8; 32],
pub counter_payout: Amount,
pub next_per_update_point: PublicKey,
}
impl_dlc_writeable!(SettleOffer, SETTLE_CHANNEL_OFFER_TYPE, {
(channel_id, writeable),
(counter_payout, writeable),
(next_per_update_point, writeable)
});
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "use-serde",
derive(serde::Serialize, serde::Deserialize),
serde(rename_all = "camelCase")
)]
pub struct SettleAccept {
#[cfg_attr(
feature = "use-serde",
serde(
serialize_with = "crate::serde_utils::serialize_hex",
deserialize_with = "crate::serde_utils::deserialize_hex_array"
)
)]
pub channel_id: [u8; 32],
pub next_per_update_point: PublicKey,
pub settle_adaptor_signature: EcdsaAdaptorSignature,
}
impl_dlc_writeable!(SettleAccept, SETTLE_CHANNEL_ACCEPT_TYPE, {
(channel_id, writeable),
(next_per_update_point, writeable),
(settle_adaptor_signature, {cb_writeable, write_ecdsa_adaptor_signature, read_ecdsa_adaptor_signature})
});
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "use-serde",
derive(serde::Serialize, serde::Deserialize),
serde(rename_all = "camelCase")
)]
pub struct SettleConfirm {
#[cfg_attr(
feature = "use-serde",
serde(
serialize_with = "crate::serde_utils::serialize_hex",
deserialize_with = "crate::serde_utils::deserialize_hex_array"
)
)]
pub channel_id: [u8; 32],
pub prev_per_update_secret: SecretKey,
pub settle_adaptor_signature: EcdsaAdaptorSignature,
}
impl_dlc_writeable!(SettleConfirm, SETTLE_CHANNEL_CONFIRM_TYPE, {
(channel_id, writeable),
(prev_per_update_secret, writeable),
(settle_adaptor_signature, {cb_writeable, write_ecdsa_adaptor_signature, read_ecdsa_adaptor_signature})
});
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "use-serde",
derive(serde::Serialize, serde::Deserialize),
serde(rename_all = "camelCase")
)]
pub struct SettleFinalize {
#[cfg_attr(
feature = "use-serde",
serde(
serialize_with = "crate::serde_utils::serialize_hex",
deserialize_with = "crate::serde_utils::deserialize_hex_array"
)
)]
pub channel_id: [u8; 32],
pub prev_per_update_secret: SecretKey,
}
impl_dlc_writeable!(SettleFinalize, SETTLE_CHANNEL_FINALIZE_TYPE, {
(channel_id, writeable),
(prev_per_update_secret, writeable)
});
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(
feature = "use-serde",
derive(serde::Serialize, serde::Deserialize),
serde(rename_all = "camelCase")
)]
pub struct RenewOffer {
#[cfg_attr(
feature = "use-serde",
serde(
serialize_with = "crate::serde_utils::serialize_hex",
deserialize_with = "crate::serde_utils::deserialize_hex_array"
)
)]
pub channel_id: [u8; 32],
pub temporary_contract_id: [u8; 32],
pub counter_payout: Amount,
pub next_per_update_point: PublicKey,
pub contract_info: ContractInfo,
pub cet_locktime: u32,
pub refund_locktime: u32,
pub cet_nsequence: u32,
}
impl_dlc_writeable!(RenewOffer, RENEW_CHANNEL_OFFER_TYPE, {
(channel_id, writeable),
(temporary_contract_id, writeable),
(counter_payout, writeable),
(next_per_update_point, writeable),
(contract_info, writeable),
(cet_locktime, writeable),
(refund_locktime, writeable),
(cet_nsequence, writeable)
});
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "use-serde",
derive(serde::Serialize, serde::Deserialize),
serde(rename_all = "camelCase")
)]
pub struct RenewAccept {
#[cfg_attr(
feature = "use-serde",
serde(
serialize_with = "crate::serde_utils::serialize_hex",
deserialize_with = "crate::serde_utils::deserialize_hex_array"
)
)]
pub channel_id: [u8; 32],
pub next_per_update_point: PublicKey,
pub cet_adaptor_signatures: CetAdaptorSignatures,
pub refund_signature: Signature,
}
impl_dlc_writeable!(RenewAccept, RENEW_CHANNEL_ACCEPT_TYPE, {
(channel_id, writeable),
(next_per_update_point, writeable),
(cet_adaptor_signatures, writeable),
(refund_signature, writeable)
});
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "use-serde",
derive(serde::Serialize, serde::Deserialize),
serde(rename_all = "camelCase")
)]
pub struct RenewConfirm {
#[cfg_attr(
feature = "use-serde",
serde(
serialize_with = "crate::serde_utils::serialize_hex",
deserialize_with = "crate::serde_utils::deserialize_hex_array"
)
)]
pub channel_id: [u8; 32],
pub buffer_adaptor_signature: EcdsaAdaptorSignature,
pub cet_adaptor_signatures: CetAdaptorSignatures,
pub refund_signature: Signature,
}
impl_dlc_writeable!(RenewConfirm, RENEW_CHANNEL_CONFIRM_TYPE, {
(channel_id, writeable),
(buffer_adaptor_signature, {cb_writeable, write_ecdsa_adaptor_signature, read_ecdsa_adaptor_signature}),
(cet_adaptor_signatures, writeable),
(refund_signature, writeable)
});
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "use-serde",
derive(serde::Serialize, serde::Deserialize),
serde(rename_all = "camelCase")
)]
pub struct RenewFinalize {
#[cfg_attr(
feature = "use-serde",
serde(
serialize_with = "crate::serde_utils::serialize_hex",
deserialize_with = "crate::serde_utils::deserialize_hex_array"
)
)]
pub channel_id: [u8; 32],
pub per_update_secret: SecretKey,
pub buffer_adaptor_signature: EcdsaAdaptorSignature,
}
impl_dlc_writeable!(RenewFinalize, RENEW_CHANNEL_FINALIZE_TYPE, {
(channel_id, writeable),
(per_update_secret, writeable),
(buffer_adaptor_signature, {cb_writeable, write_ecdsa_adaptor_signature, read_ecdsa_adaptor_signature})
});
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
serde(rename_all = "camelCase")
)]
pub struct RenewRevoke {
#[cfg_attr(
feature = "serde",
serde(
serialize_with = "crate::serde_utils::serialize_hex",
deserialize_with = "crate::serde_utils::deserialize_hex_array"
)
)]
pub channel_id: [u8; 32],
pub per_update_secret: SecretKey,
}
impl_dlc_writeable!(RenewRevoke, RENEW_CHANNEL_REVOKE_TYPE, {
(channel_id, writeable),
(per_update_secret, writeable)
});
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "use-serde",
derive(serde::Serialize, serde::Deserialize),
serde(rename_all = "camelCase")
)]
pub struct CollaborativeCloseOffer {
#[cfg_attr(
feature = "use-serde",
serde(
serialize_with = "crate::serde_utils::serialize_hex",
deserialize_with = "crate::serde_utils::deserialize_hex_array"
)
)]
pub channel_id: [u8; 32],
pub counter_payout: Amount,
pub close_signature: Signature,
}
impl_dlc_writeable!(CollaborativeCloseOffer, COLLABORATIVE_CLOSE_OFFER_TYPE, {
(channel_id, writeable),
(counter_payout, writeable),
(close_signature, writeable)
});
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "use-serde",
derive(serde::Serialize, serde::Deserialize),
serde(rename_all = "camelCase")
)]
pub struct Reject {
#[cfg_attr(
feature = "use-serde",
serde(
serialize_with = "crate::serde_utils::serialize_hex",
deserialize_with = "crate::serde_utils::deserialize_hex_array"
)
)]
pub channel_id: [u8; 32],
}
impl_dlc_writeable!(Reject, REJECT, { (channel_id, writeable) });