Skip to content

Commit

Permalink
featurize all the things
Browse files Browse the repository at this point in the history
  • Loading branch information
bennyhodl committed Nov 8, 2024
1 parent 97bfb74 commit 11da8bd
Show file tree
Hide file tree
Showing 17 changed files with 133 additions and 81 deletions.
2 changes: 1 addition & 1 deletion ddk-node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ repository = "https://github.com/bennyhodl/dlcdevkit"
edition = "2021"

[dependencies]
ddk = { version = "0.0.12", path = "../ddk/", features = ["lightning", "marketplace"] }
ddk = { version = "0.0.12", path = "../ddk/", features = ["lightning", "marketplace", "sled", "kormir"] }
ddk-payouts = { version = "0.0.12", path = "../payouts" }

anyhow = "1.0.86"
Expand Down
4 changes: 2 additions & 2 deletions ddk-node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use ddk::builder::Builder;
use ddk::dlc_manager::contract::contract_input::ContractInput;
use ddk::dlc_manager::Oracle as DlcOracle;
use ddk::dlc_manager::Storage as DlcStorage;
use ddk::oracle::KormirOracleClient;
use ddk::storage::SledStorage;
use ddk::oracle::kormir::KormirOracleClient;
use ddk::storage::sled::SledStorage;
use ddk::transport::lightning::LightningTransport;
use ddk::util::serialize_contract;
use ddk::DlcDevKit;
Expand Down
32 changes: 24 additions & 8 deletions ddk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,19 @@ homepage = "https://dlcdevkit.com"
readme = "../README.md"

[features]
nostr = ["dep:nostr-rs", "dep:nostr-sdk", "dep:nostr-sqlite", "dep:nostr-relay-pool", "dep:base64"]
marketplace = ["dep:nostr-rs", "dep:nostr-sdk", "dep:base64"]

# transport features
nostr = ["dep:nostr-rs", "dep:nostr-sdk", "dep:nostr-sqlite", "dep:nostr-relay-pool", "dep:base64"]
lightning = ["dep:lightning-net-tokio"]

# oracle features
kormir = ["dep:kormir", "dep:reqwest"]
p2pderivatives = ["dep:reqwest"]

# storage features
sled = ["dep:sled"]

[dependencies]
# dlc = { version = "0.7.0", features = ["use-serde"] }
# dlc-manager = { version = "0.7.0", features = ["use-serde"] }
Expand All @@ -29,30 +38,26 @@ dlc-trie = { version = "0.7.0", git = "https://github.com/bennyhodl/rust-dlc", b
# dlc-trie = { version = "0.7.0", path = "../../rust-dlc/dlc-trie", features = ["use-serde"] }


# kormir = "0.3.0"
kormir = { version = "0.3.0", git = "https://github.com/bennyhodl/kormir", branch = "rust-dlc-async"}
# kormir = { version = "0.3.0", path = "../../kormir/kormir" }

bitcoin = { version = "0.32.2", features = ["rand", "serde"] }
bdk_esplora = { version = "0.19", features = ["blocking", "async"] }
bdk_wallet = { version = "=1.0.0-beta.5", features = ["bdk_file_store"] }
bdk_chain = "0.20.0"
anyhow = "1.0.75"
lightning = { version = "0.0.125", default-features = false, features = ["grind_signatures", "std"] }
reqwest = { version = "0.12.9", features = ["blocking"] }
serde = { version = "1.0.192", features = ["derive"] }
serde_json = "1.0.108"
thiserror = "1.0.50"
tokio = { version = "1.34.0", features = ["full"] }
tracing = "0.1.40"
uuid = { version = "1.8.0", features = ["v4"] }
chrono = { version = "0.4.38", features = ["serde"] }
sled = "0.34.7"
async-trait = "0.1.80"

hex = "0.4.3"
crossbeam = "0.8.4"

# storage features
sled = { version = "0.34.7", optional = true }

# Nostr transport dependencies
base64 = { version = "0.13.0" , optional = true }
nostr-rs = { package = "nostr", version = "0.35.0", features = ["std"], optional = true }
Expand All @@ -63,8 +68,19 @@ nostr-relay-pool = { version = "0.35.0", optional = true }
# lightning transport
lightning-net-tokio = { version = "0.0.125", optional = true }

# oracle feature
reqwest = { version = "0.12.9", features = ["blocking"], optional = true }
# kormir = "0.3.0"
kormir = { version = "0.3.0", git = "https://github.com/bennyhodl/kormir", branch = "rust-dlc-async", optional = true }
# kormir = { version = "0.3.0", path = "../../kormir/kormir" }

[dev-dependencies]
test-log = { version = "0.2.16", features = ["trace"] }
rstest = "0.22.0"
ddk-payouts = { path = "../payouts/" }
bitcoincore-rpc = "0.19.0"

[[example]]
name = "lighnting"
path = "examples/ddk.rs"
required-features = ["lightning", "kormir", "sled"]
8 changes: 4 additions & 4 deletions ddk/examples/ddk.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
use anyhow::Result;
use bitcoin::key::rand::Fill;
use ddk::builder::Builder;
use ddk::oracle::P2PDOracleClient;
use ddk::storage::SledStorage;
use ddk::oracle::kormir::KormirOracleClient;
use ddk::storage::sled::SledStorage;
use ddk::transport::lightning::LightningTransport;
use std::env::current_dir;
use std::sync::Arc;

type ApplicationDdk = ddk::DlcDevKit<LightningTransport, SledStorage, P2PDOracleClient>;
type ApplicationDdk = ddk::DlcDevKit<LightningTransport, SledStorage, KormirOracleClient>;

#[tokio::main]
async fn main() -> Result<()> {
let transport = Arc::new(LightningTransport::new(&[0u8; 32], 1776)?);
let storage = Arc::new(SledStorage::new(current_dir()?.to_str().unwrap())?);
let oracle_client = Arc::new(P2PDOracleClient::new("host").await?);
let oracle_client = Arc::new(KormirOracleClient::new("host").await?);

let mut seed_bytes = [0u8; 32];
seed_bytes.try_fill(&mut bitcoin::key::rand::thread_rng())?;
Expand Down
5 changes: 4 additions & 1 deletion ddk/src/ddk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,10 @@ where
mod tests {
use std::time::{Duration, SystemTime, UNIX_EPOCH};

use crate::{test_util::{generate_blocks, test_ddk, TestSuite}, Transport};
use crate::{
test_util::{generate_blocks, test_ddk, TestSuite},
Transport,
};
use dlc_manager::{
contract::{contract_input::ContractInput, Contract},
Storage,
Expand Down
4 changes: 2 additions & 2 deletions ddk/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ pub enum WalletError {
Lock,
#[error("Error syncing the internal BDK wallet.")]
SyncError,
#[error("Storage error.")]
StorageError(#[from] sled::Error),
#[error("Storage error. {0}")]
StorageError(String),
#[error("Error with deriving signer: {0}")]
SignerError(String),
#[error("Wallet call to esplora: {0}")]
Expand Down
2 changes: 1 addition & 1 deletion ddk/src/nostr/marketplace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ where
tracing::info!("Oracle attestation. Saved to storage.")
}
Kind::Custom(88) => {
let announcement = crate::util::oracle_announcement_from_str(&event.content).unwrap();
let announcement = super::oracle_announcement_from_str(&event.content).unwrap();
storage.save_announcement(announcement).unwrap();
tracing::info!("Oracle announcement. Saved to storage.")
}
Expand Down
17 changes: 17 additions & 0 deletions ddk/src/nostr/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
use dlc_messages::oracle_msgs::{OracleAnnouncement, OracleAttestation};
use lightning::io::Cursor;
use lightning::util::ser::Readable;
use nostr_rs::{Filter, Kind, PublicKey as NostrPublicKey, Timestamp};

/// Nostr [dlc_messages::oracle_msgs::OracleAnnouncement] marketplace.
Expand All @@ -20,3 +23,17 @@ pub fn create_oracle_message_filter(since: Timestamp) -> Filter {
.kinds([ORACLE_ANNOUNCMENT_KIND, ORACLE_ATTESTATION_KIND])
.since(since)
}

pub fn oracle_announcement_from_str(content: &str) -> anyhow::Result<OracleAnnouncement> {
let bytes = base64::decode(content)?;
let mut cursor = Cursor::new(bytes);
OracleAnnouncement::read(&mut cursor)
.map_err(|_| anyhow::anyhow!("could not get oracle announcement"))
}

pub fn oracle_attestation_from_str(content: &str) -> anyhow::Result<OracleAttestation> {
let bytes = base64::decode(content)?;
let mut cursor = Cursor::new(bytes);
OracleAttestation::read(&mut cursor)
.map_err(|_| anyhow::anyhow!("could not read oracle attestation"))
}
6 changes: 3 additions & 3 deletions ddk/src/oracle/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ pub struct MemoryOracle {
pub oracle: Kormir<MemoryStorage>,
}

impl MemoryOracle {
pub fn new() -> Self {
impl Default for MemoryOracle {
fn default() -> Self {
let mut seed: [u8; 64] = [0; 64];
bitcoin::key::rand::thread_rng().fill(&mut seed);
let xpriv = Xpriv::new_master(bitcoin::Network::Regtest, &seed).unwrap();
Expand Down Expand Up @@ -74,7 +74,7 @@ mod tests {

#[tokio::test]
async fn get_and_sign() {
let oracle = MemoryOracle::new();
let oracle = MemoryOracle::default();
let expiry = TimeDelta::seconds(15);
let timestamp: u32 = Local::now()
.checked_add_signed(expiry)
Expand Down
9 changes: 4 additions & 5 deletions ddk/src/oracle/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
mod kormir;
#[cfg(feature = "kormir")]
pub mod kormir;
pub mod memory;
mod p2p_derivatives;

pub use kormir::KormirOracleClient;
pub use p2p_derivatives::P2PDOracleClient;
#[cfg(feature = "p2pderivatives")]
pub mod p2p_derivatives;
11 changes: 3 additions & 8 deletions ddk/src/storage/memory.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use crate::transport::PeerInformation;
use crate::Storage;
use bdk_chain::Merge;
use bdk_wallet::ChangeSet;
use dlc_manager::{channel::Channel, contract::Contract, ChannelId, ContractId};
use dlc_messages::oracle_msgs::OracleAnnouncement;
use std::collections::HashMap;
use std::sync::RwLock;

#[derive(Default, Debug)]
pub struct MemoryStorage {
peers: RwLock<HashMap<String, PeerInformation>>,
bdk_data: RwLock<Option<bdk_wallet::ChangeSet>>,
announcements: RwLock<Vec<kormir::OracleAnnouncement>>,
announcements: RwLock<Vec<OracleAnnouncement>>,
contracts: RwLock<HashMap<ContractId, Contract>>,
channels: RwLock<HashMap<ChannelId, Channel>>,
chain_monitor: RwLock<Option<dlc_manager::chain_monitor::ChainMonitor>>,
Expand Down Expand Up @@ -47,12 +47,7 @@ impl Storage for MemoryStorage {
&self,
changeset: &bdk_wallet::ChangeSet,
) -> Result<(), crate::error::WalletError> {
let mut persisted_changeset = self
.bdk_data
.read()
.unwrap()
.clone()
.unwrap_or(ChangeSet::default());
let mut persisted_changeset = self.bdk_data.read().unwrap().clone().unwrap_or_default();
persisted_changeset.merge(changeset.clone());
*self.bdk_data.write().unwrap() = Some(persisted_changeset);
Ok(())
Expand Down
5 changes: 2 additions & 3 deletions ddk/src/storage/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
pub mod memory;
mod sled;

pub use sled::SledStorage;
#[cfg(feature = "sled")]
pub mod sled;
26 changes: 20 additions & 6 deletions ddk/src/storage/sled/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,11 @@ impl SledStorage {

impl Storage for SledStorage {
fn persist_bdk(&self, changeset: &ChangeSet) -> Result<(), WalletError> {
let wallet_tree = self.wallet_tree()?;
let new_changeset = match wallet_tree.get(CHANGESET_KEY)? {
let wallet_tree = self.wallet_tree().map_err(sled_to_wallet_error)?;
let new_changeset = match wallet_tree
.get(CHANGESET_KEY)
.map_err(sled_to_wallet_error)?
{
Some(stored_changeset) => {
let mut stored_changeset = serde_json::from_slice::<ChangeSet>(&stored_changeset)?;
stored_changeset.merge(changeset.clone());
Expand All @@ -107,13 +110,20 @@ impl Storage for SledStorage {
None => changeset.to_owned(),
};

wallet_tree.insert(CHANGESET_KEY, serde_json::to_vec(&new_changeset)?)?;
wallet_tree
.insert(CHANGESET_KEY, serde_json::to_vec(&new_changeset)?)
.map_err(sled_to_wallet_error)?;
Ok(())
}

fn initialize_bdk(&self) -> Result<ChangeSet, WalletError> {
tracing::info!("Initializing wallet persistance.");
let changeset = match self.wallet_tree()?.get(CHANGESET_KEY)? {
let changeset = match self
.wallet_tree()
.map_err(sled_to_wallet_error)?
.get(CHANGESET_KEY)
.map_err(sled_to_wallet_error)?
{
Some(changeset) => serde_json::from_slice(&changeset)?,
None => ChangeSet::default(),
};
Expand Down Expand Up @@ -145,7 +155,7 @@ impl Storage for SledStorage {
}

fn save_announcement(&self, announcement: OracleAnnouncement) -> anyhow::Result<()> {
let marketplace = self.marketplace_tree()?;
let marketplace = self.marketplace_tree().map_err(sled_to_wallet_error)?;
let stored_announcements: Vec<OracleAnnouncement> =
match marketplace.get(MARKETPLACE_KEY)? {
Some(o) => serde_json::from_slice(&o)?,
Expand All @@ -162,7 +172,7 @@ impl Storage for SledStorage {
}

fn get_marketplace_announcements(&self) -> anyhow::Result<Vec<OracleAnnouncement>> {
let marketplace = self.marketplace_tree()?;
let marketplace = self.marketplace_tree().map_err(sled_to_wallet_error)?;
let prev_announcements = match marketplace.get(MARKETPLACE_KEY)? {
Some(o) => o.to_vec(),
None => vec![],
Expand All @@ -171,3 +181,7 @@ impl Storage for SledStorage {
Ok(announcements)
}
}

fn sled_to_wallet_error(error: sled::Error) -> WalletError {
WalletError::StorageError(error.to_string())
}
13 changes: 11 additions & 2 deletions ddk/src/storage/sled/wallet.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use super::sled_to_wallet_error;
use super::SledStorage;
use crate::error::WalletError;
use crate::KeyStorage;
Expand All @@ -6,7 +7,12 @@ use bitcoin::secp256k1::SecretKey;
impl KeyStorage for SledStorage {
fn get_secret_key(&self, key_id: [u8; 32]) -> Result<SecretKey, WalletError> {
let key = hex::encode(key_id);
let info = self.signer_tree()?.get(key)?.unwrap();
let info = self
.signer_tree()
.map_err(sled_to_wallet_error)?
.get(key)
.map_err(sled_to_wallet_error)?
.unwrap();
Ok(serde_json::from_slice::<SecretKey>(&info)?)
}

Expand All @@ -17,7 +23,10 @@ impl KeyStorage for SledStorage {
// Store the key id string instead of bytes.
let key_id = hex::encode(key_id);

self.signer_tree()?.insert(key_id, serialized_signer_info)?;
self.signer_tree()
.map_err(sled_to_wallet_error)?
.insert(key_id, serialized_signer_info)
.map_err(sled_to_wallet_error)?;
Ok(())
}
}
22 changes: 16 additions & 6 deletions ddk/src/test_util/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
use bitcoin::{
address::NetworkChecked, bip32::Xpriv, key::{rand::{Fill, Rng}, Secp256k1}, secp256k1::All, Address, Amount, Network
address::NetworkChecked,
bip32::Xpriv,
key::{
rand::{Fill, Rng},
Secp256k1,
},
secp256k1::All,
Address, Amount, Network,
};
use chrono::{Local, TimeDelta};
use ddk_payouts::enumeration::create_contract_input;
use dlc::EnumerationPayout;
use dlc_manager::{
contract::contract_input::ContractInput, manager::Manager, ContractId, SystemTimeProvider, Storage
contract::contract_input::ContractInput, manager::Manager, ContractId, Storage,
SystemTimeProvider,
};
use kormir::{Oracle, OracleAnnouncement, storage::MemoryStorage as KormirMemoryStorage};
use dlc_messages::oracle_msgs::OracleAnnouncement;
use kormir::{storage::MemoryStorage as KormirMemoryStorage, Oracle};
use std::{
fs::File,
io::Write,
Expand All @@ -19,8 +28,9 @@ use std::{
};

use crate::{
builder::Builder, chain::EsploraClient,
wallet::DlcDevKitWallet, DlcDevKit, storage::memory::MemoryStorage, transport::memory::MemoryTransport, oracle::memory::MemoryOracle,
builder::Builder, chain::EsploraClient, oracle::memory::MemoryOracle,
storage::memory::MemoryStorage, transport::memory::MemoryTransport, wallet::DlcDevKitWallet,
DlcDevKit,
};
use bitcoincore_rpc::RpcApi;

Expand All @@ -35,7 +45,7 @@ pub async fn test_ddk() -> (
ContractInput,
) {
let secp = Secp256k1::new();
let oracle = Arc::new(MemoryOracle::new());
let oracle = Arc::new(MemoryOracle::default());

let test = TestSuite::new(&secp, "send_offer", oracle.clone()).await;
let test_two = TestSuite::new(&secp, "sender_offer_two", oracle.clone()).await;
Expand Down
Loading

0 comments on commit 11da8bd

Please sign in to comment.