#![crate_name = "ddk_manager"]
#![forbid(unsafe_code)]
#![deny(non_upper_case_globals)]
#![deny(non_camel_case_types)]
#![deny(non_snake_case)]
#![deny(unused_mut)]
#![deny(dead_code)]
#![deny(unused_imports)]
#![deny(missing_docs)]
extern crate async_trait;
extern crate bitcoin;
extern crate ddk_dlc;
#[macro_use]
extern crate ddk_messages;
extern crate core;
extern crate ddk_trie;
extern crate lightning;
extern crate log;
#[cfg(feature = "fuzztarget")]
extern crate rand_chacha;
extern crate secp256k1_zkp;
pub mod chain_monitor;
pub mod channel;
pub mod channel_updater;
pub mod contract;
pub mod contract_updater;
mod conversion_utils;
pub mod error;
pub mod manager;
pub mod payout_curve;
mod utils;
use bitcoin::psbt::Psbt;
use bitcoin::{Address, Block, OutPoint, ScriptBuf, Transaction, TxOut, Txid};
use chain_monitor::ChainMonitor;
use channel::offered_channel::OfferedChannel;
use channel::signed_channel::{SignedChannel, SignedChannelStateType};
use channel::Channel;
use contract::PreClosedContract;
use contract::{offered_contract::OfferedContract, signed_contract::SignedContract, Contract};
use ddk_messages::oracle_msgs::{OracleAnnouncement, OracleAttestation};
use ddk_messages::ser_impls::{read_address, write_address};
use error::Error;
use lightning::ln::msgs::DecodeError;
use lightning::util::ser::{Readable, Writeable, Writer};
use secp256k1_zkp::{PublicKey, SecretKey, Signing};
use secp256k1_zkp::{Secp256k1, XOnlyPublicKey};
use std::collections::HashMap;
use std::ops::Deref;
use std::sync::RwLock;
pub type ContractId = [u8; 32];
pub type KeysId = [u8; 32];
pub type ChannelId = [u8; 32];
pub trait Time {
fn unix_time_now(&self) -> u64;
}
pub struct SystemTimeProvider {}
impl Time for SystemTimeProvider {
fn unix_time_now(&self) -> u64 {
let now = std::time::SystemTime::now();
now.duration_since(std::time::UNIX_EPOCH)
.expect("Unexpected time error")
.as_secs()
}
}
pub trait ContractSigner: Clone {
fn get_public_key<C: Signing>(&self, secp: &Secp256k1<C>) -> Result<PublicKey, Error>;
fn get_secret_key(&self) -> Result<SecretKey, Error>;
}
#[derive(Debug, Copy, Clone)]
pub struct SimpleSigner {
secret_key: SecretKey,
}
impl SimpleSigner {
pub fn new(secret_key: SecretKey) -> Self {
Self { secret_key }
}
}
impl ContractSigner for SimpleSigner {
fn get_public_key<C: Signing>(&self, secp: &Secp256k1<C>) -> Result<PublicKey, Error> {
Ok(self.secret_key.public_key(secp))
}
fn get_secret_key(&self) -> Result<SecretKey, Error> {
Ok(self.secret_key)
}
}
impl ContractSigner for SecretKey {
fn get_public_key<C: Signing>(&self, secp: &Secp256k1<C>) -> Result<PublicKey, Error> {
Ok(self.public_key(secp))
}
fn get_secret_key(&self) -> Result<SecretKey, Error> {
Ok(*self)
}
}
pub trait ContractSignerProvider {
type Signer: ContractSigner;
fn derive_signer_key_id(&self, is_offer_party: bool, temp_id: [u8; 32]) -> [u8; 32];
fn derive_contract_signer(&self, key_id: [u8; 32]) -> Result<Self::Signer, Error>;
fn get_secret_key_for_pubkey(&self, pubkey: &PublicKey) -> Result<SecretKey, Error>;
fn get_new_secret_key(&self) -> Result<SecretKey, Error>;
}
pub trait Wallet {
fn get_new_address(&self) -> Result<Address, Error>;
fn get_new_change_address(&self) -> Result<Address, Error>;
fn get_utxos_for_amount(
&self,
amount: u64,
fee_rate: u64,
lock_utxos: bool,
) -> Result<Vec<Utxo>, Error>;
fn import_address(&self, address: &Address) -> Result<(), Error>;
fn sign_psbt_input(&self, psbt: &mut Psbt, input_index: usize) -> Result<(), Error>;
fn unreserve_utxos(&self, outpoints: &[OutPoint]) -> Result<(), Error>;
}
#[async_trait::async_trait]
pub trait Blockchain {
async fn send_transaction(&self, transaction: &Transaction) -> Result<(), Error>;
fn get_network(&self) -> Result<bitcoin::Network, Error>;
async fn get_blockchain_height(&self) -> Result<u64, Error>;
async fn get_block_at_height(&self, height: u64) -> Result<Block, Error>;
async fn get_transaction(&self, tx_id: &Txid) -> Result<Transaction, Error>;
async fn get_transaction_confirmations(&self, tx_id: &Txid) -> Result<u32, Error>;
}
pub trait Storage {
fn get_contract(&self, id: &ContractId) -> Result<Option<Contract>, Error>;
fn get_contracts(&self) -> Result<Vec<Contract>, Error>;
fn create_contract(&self, contract: &OfferedContract) -> Result<(), Error>;
fn delete_contract(&self, id: &ContractId) -> Result<(), Error>;
fn update_contract(&self, contract: &Contract) -> Result<(), Error>;
fn get_contract_offers(&self) -> Result<Vec<OfferedContract>, Error>;
fn get_signed_contracts(&self) -> Result<Vec<SignedContract>, Error>;
fn get_confirmed_contracts(&self) -> Result<Vec<SignedContract>, Error>;
fn get_preclosed_contracts(&self) -> Result<Vec<PreClosedContract>, Error>;
fn upsert_channel(&self, channel: Channel, contract: Option<Contract>) -> Result<(), Error>;
fn delete_channel(&self, channel_id: &ChannelId) -> Result<(), Error>;
fn get_channel(&self, channel_id: &ChannelId) -> Result<Option<Channel>, Error>;
fn get_signed_channels(
&self,
channel_state: Option<SignedChannelStateType>,
) -> Result<Vec<SignedChannel>, Error>;
fn get_offered_channels(&self) -> Result<Vec<OfferedChannel>, Error>;
fn persist_chain_monitor(&self, monitor: &ChainMonitor) -> Result<(), Error>;
fn get_chain_monitor(&self) -> Result<Option<ChainMonitor>, Error>;
}
#[async_trait::async_trait]
pub trait Oracle {
fn get_public_key(&self) -> XOnlyPublicKey;
async fn get_announcement(&self, event_id: &str) -> Result<OracleAnnouncement, Error>;
async fn get_attestation(&self, event_id: &str) -> Result<OracleAttestation, Error>;
}
#[derive(Clone, Debug)]
pub struct Utxo {
pub tx_out: TxOut,
pub outpoint: OutPoint,
pub address: Address,
pub redeem_script: ScriptBuf,
pub reserved: bool,
}
impl_dlc_writeable!(Utxo, {
(tx_out, writeable),
(outpoint, writeable),
(address, {cb_writeable, write_address, read_address}),
(redeem_script, writeable),
(reserved, writeable)
});
pub struct CachedContractSignerProvider<SP: Deref, X>
where
SP::Target: ContractSignerProvider<Signer = X>,
{
pub(crate) signer_provider: SP,
pub(crate) cache: RwLock<HashMap<KeysId, X>>,
}
impl<SP: Deref, X> CachedContractSignerProvider<SP, X>
where
SP::Target: ContractSignerProvider<Signer = X>,
{
pub fn new(signer_provider: SP) -> Self {
Self {
signer_provider,
cache: RwLock::new(HashMap::new()),
}
}
}
impl<SP: Deref, X: ContractSigner> ContractSignerProvider for CachedContractSignerProvider<SP, X>
where
SP::Target: ContractSignerProvider<Signer = X>,
{
type Signer = X;
fn derive_signer_key_id(&self, is_offer_party: bool, temp_id: [u8; 32]) -> KeysId {
self.signer_provider
.derive_signer_key_id(is_offer_party, temp_id)
}
fn derive_contract_signer(&self, key_id: KeysId) -> Result<Self::Signer, Error> {
match self.cache.try_read().unwrap().get(&key_id) {
Some(signer) => Ok(signer.clone()),
None => self.signer_provider.derive_contract_signer(key_id),
}
}
fn get_secret_key_for_pubkey(&self, pubkey: &PublicKey) -> Result<SecretKey, Error> {
self.signer_provider.get_secret_key_for_pubkey(pubkey)
}
fn get_new_secret_key(&self) -> Result<SecretKey, Error> {
self.signer_provider.get_new_secret_key()
}
}