mirror of
https://github.com/aljazceru/cdk.git
synced 2025-12-20 14:14:49 +01:00
feat: tests on lnd node
This commit is contained in:
@@ -12,6 +12,7 @@ use cdk::nuts::{
|
||||
};
|
||||
use cdk::util::unix_time;
|
||||
use paste::paste;
|
||||
use tracing::instrument;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::ws::main_websocket;
|
||||
@@ -232,6 +233,7 @@ pub async fn post_mint_bolt11(
|
||||
(status = 500, description = "Server error", body = ErrorResponse, content_type = "application/json")
|
||||
)
|
||||
))]
|
||||
#[instrument(skip_all)]
|
||||
/// Request a quote for melting tokens
|
||||
pub async fn post_melt_bolt11_quote(
|
||||
State(state): State<MintState>,
|
||||
@@ -261,6 +263,7 @@ pub async fn post_melt_bolt11_quote(
|
||||
/// Get melt quote by ID
|
||||
///
|
||||
/// Get melt quote state.
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get_check_melt_bolt11_quote(
|
||||
State(state): State<MintState>,
|
||||
Path(quote_id): Path<Uuid>,
|
||||
@@ -290,6 +293,7 @@ pub async fn get_check_melt_bolt11_quote(
|
||||
/// Melt tokens for a Bitcoin payment that the mint will make for the user in exchange
|
||||
///
|
||||
/// Requests tokens to be destroyed and sent out via Lightning.
|
||||
#[instrument(skip_all)]
|
||||
pub async fn post_melt_bolt11(
|
||||
State(state): State<MintState>,
|
||||
Json(payload): Json<MeltBolt11Request<Uuid>>,
|
||||
|
||||
@@ -5,7 +5,9 @@ use axum::Router;
|
||||
use cdk::mint::Mint;
|
||||
use tokio::sync::Notify;
|
||||
use tower_http::cors::CorsLayer;
|
||||
use tracing::instrument;
|
||||
|
||||
#[instrument(skip_all)]
|
||||
pub async fn start_mint(addr: &str, port: u16, mint: Mint) -> Result<()> {
|
||||
let mint_arc = Arc::new(mint);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::Result;
|
||||
@@ -14,6 +14,7 @@ use ln_regtest_rs::bitcoin_client::BitcoinClient;
|
||||
use ln_regtest_rs::bitcoind::Bitcoind;
|
||||
use ln_regtest_rs::ln_client::{ClnClient, LightningClient, LndClient};
|
||||
use ln_regtest_rs::lnd::Lnd;
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::init_mint::start_mint;
|
||||
|
||||
@@ -93,11 +94,11 @@ pub fn get_lnd_dir(name: &str) -> PathBuf {
|
||||
dir
|
||||
}
|
||||
|
||||
pub fn get_lnd_cert_file_path(lnd_dir: &PathBuf) -> PathBuf {
|
||||
pub fn get_lnd_cert_file_path(lnd_dir: &Path) -> PathBuf {
|
||||
lnd_dir.join("tls.cert")
|
||||
}
|
||||
|
||||
pub fn get_lnd_macaroon_path(lnd_dir: &PathBuf) -> PathBuf {
|
||||
pub fn get_lnd_macaroon_path(lnd_dir: &Path) -> PathBuf {
|
||||
lnd_dir.join("data/chain/bitcoin/regtest/admin.macaroon")
|
||||
}
|
||||
|
||||
@@ -147,6 +148,7 @@ pub async fn create_lnd_backend(lnd_client: &LndClient) -> Result<CdkLnd> {
|
||||
.await?)
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
pub async fn create_mint<D, L>(addr: &str, port: u16, database: D, lighting: L) -> Result<()>
|
||||
where
|
||||
D: MintDatabase<Err = cdk_database::Error> + Send + Sync + 'static,
|
||||
|
||||
@@ -15,7 +15,8 @@ use cdk::nuts::{
|
||||
use cdk::wallet::client::{HttpClient, MintConnector};
|
||||
use cdk::wallet::{Wallet, WalletSubscription};
|
||||
use cdk_integration_tests::init_regtest::{
|
||||
get_cln_dir, get_lnd_dir, get_mint_url, get_mint_ws_url, LND_RPC_ADDR,
|
||||
get_cln_dir, get_lnd_cert_file_path, get_lnd_dir, get_lnd_macaroon_path, get_mint_port,
|
||||
get_mint_url, get_mint_ws_url, LND_RPC_ADDR, LND_TWO_RPC_ADDR,
|
||||
};
|
||||
use futures::{SinkExt, StreamExt};
|
||||
use lightning_invoice::Bolt11Invoice;
|
||||
@@ -258,7 +259,10 @@ async fn test_pay_invoice_twice() -> Result<()> {
|
||||
|
||||
let mint_quote = wallet.mint_quote(100.into(), None).await?;
|
||||
|
||||
lnd_client.pay_invoice(mint_quote.request).await?;
|
||||
lnd_client
|
||||
.pay_invoice(mint_quote.request)
|
||||
.await
|
||||
.expect("Could not pay invoice");
|
||||
|
||||
let proofs = wallet
|
||||
.mint(&mint_quote.id, SplitTarget::default(), None)
|
||||
@@ -343,13 +347,33 @@ async fn test_internal_payment() -> Result<()> {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let cln_one_dir = get_cln_dir("one");
|
||||
let cln_client = ClnClient::new(cln_one_dir.clone(), None).await?;
|
||||
let check_paid = match get_mint_port() {
|
||||
8085 => {
|
||||
let cln_one_dir = get_cln_dir("one");
|
||||
let cln_client = ClnClient::new(cln_one_dir.clone(), None).await?;
|
||||
|
||||
let payment_hash = Bolt11Invoice::from_str(&mint_quote.request)?;
|
||||
let check_paid = cln_client
|
||||
.check_incoming_payment_status(&payment_hash.payment_hash().to_string())
|
||||
.await?;
|
||||
let payment_hash = Bolt11Invoice::from_str(&mint_quote.request)?;
|
||||
cln_client
|
||||
.check_incoming_payment_status(&payment_hash.payment_hash().to_string())
|
||||
.await
|
||||
.expect("Could not check invoice")
|
||||
}
|
||||
8087 => {
|
||||
let lnd_two_dir = get_lnd_dir("two");
|
||||
let lnd_client = LndClient::new(
|
||||
format!("https://{}", LND_TWO_RPC_ADDR),
|
||||
get_lnd_cert_file_path(&lnd_two_dir),
|
||||
get_lnd_macaroon_path(&lnd_two_dir),
|
||||
)
|
||||
.await?;
|
||||
let payment_hash = Bolt11Invoice::from_str(&mint_quote.request)?;
|
||||
lnd_client
|
||||
.check_incoming_payment_status(&payment_hash.payment_hash().to_string())
|
||||
.await
|
||||
.expect("Could not check invoice")
|
||||
}
|
||||
_ => panic!("Unknown mint port"),
|
||||
};
|
||||
|
||||
match check_paid {
|
||||
InvoiceStatus::Unpaid => (),
|
||||
|
||||
@@ -25,6 +25,7 @@ use error::Error;
|
||||
use fedimint_tonic_lnd::lnrpc::fee_limit::Limit;
|
||||
use fedimint_tonic_lnd::lnrpc::payment::PaymentStatus;
|
||||
use fedimint_tonic_lnd::lnrpc::FeeLimit;
|
||||
use fedimint_tonic_lnd::tonic::Code;
|
||||
use fedimint_tonic_lnd::Client;
|
||||
use futures::{Stream, StreamExt};
|
||||
use tokio::sync::Mutex;
|
||||
@@ -76,6 +77,7 @@ impl Lnd {
|
||||
impl MintLightning for Lnd {
|
||||
type Err = cdk_lightning::Error;
|
||||
|
||||
#[instrument(skip_all)]
|
||||
fn get_settings(&self) -> Settings {
|
||||
Settings {
|
||||
mpp: false,
|
||||
@@ -84,14 +86,17 @@ impl MintLightning for Lnd {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
fn is_wait_invoice_active(&self) -> bool {
|
||||
self.wait_invoice_is_active.load(Ordering::SeqCst)
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
fn cancel_wait_invoice(&self) {
|
||||
self.wait_invoice_cancel_token.cancel()
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
async fn wait_any_invoice(
|
||||
&self,
|
||||
) -> Result<Pin<Box<dyn Stream<Item = String> + Send>>, Self::Err> {
|
||||
@@ -164,6 +169,7 @@ impl MintLightning for Lnd {
|
||||
.boxed())
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
async fn get_payment_quote(
|
||||
&self,
|
||||
melt_quote_request: &MeltQuoteBolt11Request,
|
||||
@@ -198,6 +204,23 @@ impl MintLightning for Lnd {
|
||||
max_fee: Option<Amount>,
|
||||
) -> Result<PayInvoiceResponse, Self::Err> {
|
||||
let payment_request = melt_quote.request;
|
||||
let bolt11 = Bolt11Invoice::from_str(&payment_request)?;
|
||||
|
||||
let pay_state = self
|
||||
.check_outgoing_payment(&bolt11.payment_hash().to_string())
|
||||
.await?;
|
||||
|
||||
match pay_state.status {
|
||||
MeltQuoteState::Unpaid | MeltQuoteState::Unknown | MeltQuoteState::Failed => (),
|
||||
MeltQuoteState::Paid => {
|
||||
tracing::debug!("Melt attempted on invoice already paid");
|
||||
return Err(Self::Err::InvoiceAlreadyPaid);
|
||||
}
|
||||
MeltQuoteState::Pending => {
|
||||
tracing::debug!("Melt attempted on invoice already pending");
|
||||
return Err(Self::Err::InvoicePaymentPending);
|
||||
}
|
||||
}
|
||||
|
||||
let amount_msat: u64 = match melt_quote.msat_to_pay {
|
||||
Some(amount_msat) => amount_msat.into(),
|
||||
@@ -255,6 +278,7 @@ impl MintLightning for Lnd {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(self, description))]
|
||||
async fn create_invoice(
|
||||
&self,
|
||||
amount: Amount,
|
||||
@@ -292,6 +316,7 @@ impl MintLightning for Lnd {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
async fn check_incoming_invoice_status(
|
||||
&self,
|
||||
request_lookup_id: &str,
|
||||
@@ -324,6 +349,7 @@ impl MintLightning for Lnd {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
async fn check_outgoing_payment(
|
||||
&self,
|
||||
payment_hash: &str,
|
||||
@@ -332,15 +358,32 @@ impl MintLightning for Lnd {
|
||||
payment_hash: hex::decode(payment_hash).map_err(|_| Error::InvalidHash)?,
|
||||
no_inflight_updates: true,
|
||||
};
|
||||
let mut payment_stream = self
|
||||
|
||||
let payment_response = self
|
||||
.client
|
||||
.lock()
|
||||
.await
|
||||
.router()
|
||||
.track_payment_v2(track_request)
|
||||
.await
|
||||
.unwrap()
|
||||
.into_inner();
|
||||
.await;
|
||||
|
||||
let mut payment_stream = match payment_response {
|
||||
Ok(stream) => stream.into_inner(),
|
||||
Err(err) => {
|
||||
let err_code = err.code();
|
||||
if err_code == Code::NotFound {
|
||||
return Ok(PayInvoiceResponse {
|
||||
payment_lookup_id: payment_hash.to_string(),
|
||||
payment_preimage: None,
|
||||
status: MeltQuoteState::Unknown,
|
||||
total_spent: Amount::ZERO,
|
||||
unit: self.get_settings().unit,
|
||||
});
|
||||
} else {
|
||||
return Err(cdk_lightning::Error::UnknownPaymentState);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
while let Some(update_result) = payment_stream.next().await {
|
||||
match update_result {
|
||||
|
||||
@@ -21,6 +21,7 @@ use crate::util::unix_time;
|
||||
use crate::{cdk_lightning, Amount, Error};
|
||||
|
||||
impl Mint {
|
||||
#[instrument(skip_all)]
|
||||
fn check_melt_request_acceptable(
|
||||
&self,
|
||||
amount: Amount,
|
||||
|
||||
@@ -28,7 +28,7 @@ cleanup() {
|
||||
}
|
||||
|
||||
# Set up trap to call cleanup on script exit
|
||||
# trap cleanup EXIT
|
||||
trap cleanup EXIT
|
||||
|
||||
# Create a temporary directory
|
||||
export cdk_itests=$(mktemp -d)
|
||||
@@ -47,7 +47,10 @@ export MINT_DATABASE="$1";
|
||||
|
||||
cargo build -p cdk-integration-tests
|
||||
cargo build --bin regtest_mint
|
||||
# cargo run --bin regtest_mint > "$cdk_itests/mint.log" 2>&1 &
|
||||
cargo run --bin regtest_mint &
|
||||
|
||||
echo $cdk_itests
|
||||
# Capture its PID
|
||||
CDK_ITEST_MINT_BIN_PID=$!
|
||||
|
||||
@@ -82,10 +85,10 @@ done
|
||||
|
||||
|
||||
# Run cargo test
|
||||
# cargo test -p cdk-integration-tests --test regtest
|
||||
cargo test -p cdk-integration-tests --test regtest
|
||||
|
||||
# # Run cargo test with the http_subscription feature
|
||||
# cargo test -p cdk-integration-tests --test regtest --features http_subscription
|
||||
cargo test -p cdk-integration-tests --test regtest --features http_subscription
|
||||
|
||||
# Run tests with lnd mint
|
||||
export cdk_itests_mint_port=8087;
|
||||
|
||||
Reference in New Issue
Block a user