Skip to content

Commit

Permalink
Merge branch 'main' into bilthon-test
Browse files Browse the repository at this point in the history
  • Loading branch information
grunch authored Nov 7, 2024
2 parents 1689ba9 + df845f9 commit 18279af
Show file tree
Hide file tree
Showing 13 changed files with 281 additions and 87 deletions.
8 changes: 6 additions & 2 deletions docker/DOCKER.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ The `compose.yml` file is configured as follows:
```yaml
services:
mostro:
build: .
build:
context: ..
dockerfile: docker/Dockerfile
volumes:
- ~/mostro:/config # settings.toml and mostro.db
- ./config:/config # settings.toml and mostro.db
- ~/.polar/networks/1/volumes/lnd:/lnd # LND data
platform: linux/amd64

```

## Building and Running the Docker Container
Expand Down
35 changes: 20 additions & 15 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,32 +1,37 @@
# Build stage
FROM rust:latest as builder

# Install dependencies
RUN apt-get update && \
apt-get install -y cmake build-essential libsqlite3-dev pkg-config libssl-dev

# Clone repository
RUN git clone https://github.com/MostroP2P/mostro.git /mostro
FROM rust:1.81 AS builder

# Set working directory
WORKDIR /mostro

# Copy source code
COPY . .

# Install build dependencies
RUN apt-get update && \
apt-get install -y cmake build-essential libsqlite3-dev pkg-config libssl-dev protobuf-compiler

# Build the project in release mode
RUN cargo build --release

# Production stage
FROM rust:slim-bookworm
FROM debian:bookworm-slim

# Copy builded binary from build stage
# Copy built binary from build stage
COPY --from=builder /mostro/target/release/mostrod /usr/local/bin/mostrod

WORKDIR /mostro

# Copy settings and empty database
COPY ./settings.docker.toml /mostro/settings.docker.toml
COPY ./empty.mostro.db /mostro/empty.mostro.db
COPY --chown=mostrouser:mostrouser ./docker/settings.docker.toml ./docker/empty.mostro.db ./

# Copy start script
COPY start.sh /mostro/start.sh
RUN chmod +x /mostro/start.sh
COPY --chown=mostrouser:mostrouser ./docker/start.sh ./start.sh
RUN chmod +x ./start.sh

# Add a non-root user and switch to it
RUN useradd -m mostrouser
USER mostrouser

# Start mostro (copy settings and database if it's not created yet)
CMD ["/mostro/start.sh"]
ENTRYPOINT ["./start.sh"]
4 changes: 3 additions & 1 deletion docker/compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
services:
mostro:
build: .
build:
context: ..
dockerfile: docker/Dockerfile
volumes:
- ./config:/config # settings.toml and mostro.db
- ~/.polar/networks/1/volumes/lnd:/lnd # LND data
Expand Down
2 changes: 1 addition & 1 deletion docker/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ if [ ! -f /config/mostro.db ]; then
fi

# Run application
/usr/local/bin/mostrod -d /config
/usr/local/bin/mostrod -d /config
9 changes: 6 additions & 3 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,12 @@ pub async fn run(
};

let event = unwrap_gift_wrap(&my_keys, &event)?;
// Here we discard messages older than the real since parameter
let now = chrono::Utc::now().timestamp() as u64;
if event.rumor.created_at.as_u64() < now {
// We discard events older than 10 seconds
let since_time = chrono::Utc::now()
.checked_sub_signed(chrono::Duration::seconds(10))
.unwrap()
.timestamp() as u64;
if event.rumor.created_at.as_u64() < since_time {
continue;
}

Expand Down
3 changes: 2 additions & 1 deletion src/app/admin_add_solver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ pub async fn admin_add_solver_action(
let message = Message::new_dispute(request_id, None, Action::AdminAddSolver, None);
let message = message.as_json()?;
// Send the message
send_dm(&event.sender, message).await?;
let sender_keys = crate::util::get_keys().unwrap();
send_dm(&event.sender, sender_keys, message).await?;

Ok(())
}
24 changes: 16 additions & 8 deletions src/app/admin_cancel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use std::str::FromStr;
use crate::db::{find_dispute_by_order_id, is_assigned_solver};
use crate::lightning::LndConnector;
use crate::nip33::new_event;
use crate::util::{send_dm, send_new_order_msg, update_order_event};
use crate::NOSTR_CLIENT;
use crate::util::{get_nostr_client, send_dm, send_new_order_msg, update_order_event};

use anyhow::{Error, Result};
use mostro_core::dispute::Status as DisputeStatus;
Expand Down Expand Up @@ -66,7 +65,8 @@ pub async fn admin_cancel_action(
None,
);
if let Ok(message) = message.as_json() {
let _ = send_dm(&event.sender, message).await;
let sender_keys = crate::util::get_keys().unwrap();
let _ = send_dm(&event.sender, sender_keys, message).await;
}
return Ok(());
}
Expand Down Expand Up @@ -117,7 +117,14 @@ pub async fn admin_cancel_action(
// nip33 kind with dispute id as identifier
let event = new_event(my_keys, "", dispute_id.to_string(), tags)?;

NOSTR_CLIENT.get().unwrap().send_event(event).await?;
match get_nostr_client() {
Ok(client) => {
if let Err(e) = client.send_event(event).await {
error!("Failed to send dispute status event: {}", e);
}
}
Err(e) => error!("Failed to get Nostr client: {}", e),
}
}

// We publish a new replaceable kind nostr event with the status updated
Expand All @@ -128,7 +135,8 @@ pub async fn admin_cancel_action(
let message = Message::new_order(request_id, Some(order.id), Action::AdminCanceled, None);
let message = message.as_json()?;
// Message to admin
send_dm(&event.sender, message.clone()).await?;
let sender_keys = crate::util::get_keys().unwrap();
send_dm(&event.sender, sender_keys, message.clone()).await?;

let (seller_pubkey, buyer_pubkey) = match (&order.seller_pubkey, &order.buyer_pubkey) {
(Some(seller), Some(buyer)) => (
Expand All @@ -138,9 +146,9 @@ pub async fn admin_cancel_action(
(None, _) => return Err(Error::msg("Missing seller pubkey")),
(_, None) => return Err(Error::msg("Missing buyer pubkey")),
};

send_dm(&seller_pubkey, message.clone()).await?;
send_dm(&buyer_pubkey, message).await?;
let sender_keys = crate::util::get_keys().unwrap();
send_dm(&seller_pubkey, sender_keys.clone(), message.clone()).await?;
send_dm(&buyer_pubkey, sender_keys, message).await?;

Ok(())
}
36 changes: 29 additions & 7 deletions src/app/admin_settle.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::db::{find_dispute_by_order_id, is_assigned_solver};
use crate::lightning::LndConnector;
use crate::nip33::new_event;
use crate::util::{send_dm, send_new_order_msg, settle_seller_hold_invoice, update_order_event};
use crate::NOSTR_CLIENT;
use crate::util::{
get_nostr_client, send_dm, send_new_order_msg, settle_seller_hold_invoice, update_order_event,
};

use anyhow::{Error, Result};
use mostro_core::dispute::Status as DisputeStatus;
Expand Down Expand Up @@ -67,7 +68,8 @@ pub async fn admin_settle_action(
None,
);
if let Ok(message) = message.as_json() {
let _ = send_dm(&event.sender, message).await;
let sender_keys = crate::util::get_keys().unwrap();
let _ = send_dm(&event.sender, sender_keys, message).await;
}
return Ok(());
}
Expand Down Expand Up @@ -123,7 +125,16 @@ pub async fn admin_settle_action(
// nip33 kind with dispute id as identifier
let event = new_event(my_keys, "", dispute_id.to_string(), tags)?;

NOSTR_CLIENT.get().unwrap().send_event(event).await?;
match get_nostr_client() {
Ok(client) => {
if let Err(e) = client.send_event(event).await {
error!("Failed to send dispute settlement event: {}", e);
}
}
Err(e) => {
error!("Failed to get Nostr client for dispute settlement: {}", e);
}
}
}
// We create a Message for settle
let message = Message::new_order(
Expand All @@ -134,12 +145,23 @@ pub async fn admin_settle_action(
);
let message = message.as_json()?;
// Message to admin
send_dm(&event.sender, message.clone()).await?;
let sender_keys = crate::util::get_keys().unwrap();
send_dm(&event.sender, sender_keys.clone(), message.clone()).await?;
if let Some(ref seller_pubkey) = order_updated.seller_pubkey {
send_dm(&PublicKey::from_str(seller_pubkey)?, message.clone()).await?;
send_dm(
&PublicKey::from_str(seller_pubkey)?,
sender_keys.clone(),
message.clone(),
)
.await?;
}
if let Some(ref buyer_pubkey) = order_updated.buyer_pubkey {
send_dm(&PublicKey::from_str(buyer_pubkey)?, message.clone()).await?;
send_dm(
&PublicKey::from_str(buyer_pubkey)?,
sender_keys,
message.clone(),
)
.await?;
}

let _ = do_payment(order_updated, Some(request_id)).await;
Expand Down
26 changes: 19 additions & 7 deletions src/app/admin_take_dispute.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::db::find_solver_pubkey;
use crate::nip33::new_event;
use crate::util::{send_cant_do_msg, send_dm, send_new_order_msg};
use crate::NOSTR_CLIENT;
use crate::util::{get_nostr_client, send_cant_do_msg, send_dm, send_new_order_msg};

use anyhow::{Error, Result};
use mostro_core::dispute::{Dispute, Status};
Expand Down Expand Up @@ -112,7 +111,8 @@ pub async fn admin_take_dispute_action(
Some(Content::Order(new_order)),
);
let message = message.as_json()?;
send_dm(&event.sender, message).await?;
let sender_keys = crate::util::get_keys().unwrap();
send_dm(&event.sender, sender_keys, message).await?;
// Now we create a message to both parties of the order
// to them know who will assist them on the dispute
let solver_pubkey = Peer::new(event.sender.to_hex());
Expand All @@ -138,9 +138,9 @@ pub async fn admin_take_dispute_action(
(None, _) => return Err(Error::msg("Missing seller pubkey")),
(_, None) => return Err(Error::msg("Missing buyer pubkey")),
};

send_dm(&buyer_pubkey, msg_to_buyer.as_json()?).await?;
send_dm(&seller_pubkey, msg_to_seller.as_json()?).await?;
let sender_keys = crate::util::get_keys().unwrap();
send_dm(&buyer_pubkey, sender_keys.clone(), msg_to_buyer.as_json()?).await?;
send_dm(&seller_pubkey, sender_keys, msg_to_seller.as_json()?).await?;
// We create a tag to show status of the dispute
let tags: Vec<Tag> = vec![
Tag::custom(
Expand All @@ -159,7 +159,19 @@ pub async fn admin_take_dispute_action(
// nip33 kind with dispute id as identifier
let event = new_event(&crate::util::get_keys()?, "", dispute_id.to_string(), tags)?;
info!("Dispute event to be published: {event:#?}");
NOSTR_CLIENT.get().unwrap().send_event(event).await?;

let client = get_nostr_client().map_err(|e| {
info!(
"Failed to get nostr client for dispute {}: {}",
dispute_id, e
);
e
})?;

client.send_event(event).await.map_err(|e| {
info!("Failed to send dispute {} status event: {}", dispute_id, e);
e
})?;

Ok(())
}
8 changes: 5 additions & 3 deletions src/app/dispute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ use std::str::FromStr;

use crate::db::find_dispute_by_order_id;
use crate::nip33::new_event;
use crate::util::{send_cant_do_msg, send_new_order_msg};
use crate::NOSTR_CLIENT;
use crate::util::{get_nostr_client, send_cant_do_msg, send_new_order_msg};

use anyhow::{Error, Result};
use mostro_core::dispute::Dispute;
Expand Down Expand Up @@ -178,7 +177,10 @@ pub async fn dispute_action(
// nip33 kind with dispute id as identifier
let event = new_event(my_keys, "", dispute.id.to_string(), tags)?;
info!("Dispute event to be published: {event:#?}");
NOSTR_CLIENT.get().unwrap().send_event(event).await?;

if let Ok(client) = get_nostr_client() {
let _ = client.send_event(event).await;
}

Ok(())
}
29 changes: 15 additions & 14 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ use lightning::LndConnector;
use nostr_sdk::prelude::*;
use scheduler::start_scheduler;
use std::env;
use std::process::exit;
use std::sync::Arc;
use std::sync::OnceLock;
use tokio::sync::Mutex;
use tracing::{error, info};
use tracing_subscriber::{fmt, prelude::*, EnvFilter};
use util::invoice_subscribe;
use util::{get_nostr_client, invoice_subscribe};

static MOSTRO_CONFIG: OnceLock<Settings> = OnceLock::new();
static NOSTR_CLIENT: OnceLock<Client> = OnceLock::new();
Expand Down Expand Up @@ -70,11 +71,18 @@ async fn main() -> Result<()> {
.pubkey(my_keys.public_key())
.since(Timestamp::now() - 172800);

NOSTR_CLIENT
.get()
.unwrap()
.subscribe(vec![subscription], None)
.await;
let client = match get_nostr_client() {
Ok(client) => client,
Err(e) => {
tracing::error!("Failed to initialize Nostr client. Cannot proceed: {e}");
// Clean up any resources if needed
exit(1)
}
};

// Client subscription
client.subscribe(vec![subscription], None).await;

let mut ln_client = LndConnector::new().await?;

if let Ok(held_invoices) = find_held_invoices(&pool).await {
Expand All @@ -91,14 +99,7 @@ async fn main() -> Result<()> {
// Start scheduler for tasks
start_scheduler(rate_list.clone()).await;

run(
my_keys,
NOSTR_CLIENT.get().unwrap(),
&mut ln_client,
pool,
rate_list.clone(),
)
.await
run(my_keys, client, &mut ln_client, pool, rate_list.clone()).await
}

#[cfg(test)]
Expand Down
Loading

0 comments on commit 18279af

Please sign in to comment.