Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Remove active gateway #4427

Merged
merged 5 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions devimint/src/devfed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ pub async fn dev_fed(process_mgr: &ProcessManager) -> Result<DevFed> {

info!(target: LOG_DEVIMINT, "federation and gateways started");

std::env::set_var("GWID_CLN", gw_cln.gateway_id().await?);
std::env::set_var("GWID_LND", gw_lnd.gateway_id().await?);
Comment on lines +55 to +56
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was going to suggest prefixing with FM_ but then realized that the only reason we did this in the past was to be able to copy all relevant envirment variables into the mprocs shell IIRC. But devimint fixes this for us now. So it would probably make more sense to remove the FM_ prefixes!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It"s good to have project-specfic prefixes in long living env variables, as it makes chances of accidental conflicts lower. So we should keep LM_. @m1sterc001guy @justinmoon

info!(target: LOG_DEVIMINT, "Setup gateway environment variables");

tokio::try_join!(gw_cln.connect_fed(&fed), gw_lnd.connect_fed(&fed), async {
info!(target: LOG_DEVIMINT, "Joining federation with the main client");
cmd!(fed.internal_client(), "join-federation", fed.invite_code()?)
Expand Down
31 changes: 22 additions & 9 deletions devimint/src/federation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use fedimintd::fedimintd::FM_EXTRA_DKG_META_VAR;
use fs_lock::FileLock;
use futures::future::join_all;
use rand::Rng;
use semver::VersionReq;
use tracing::{debug, info};

use super::external::Bitcoind;
Expand Down Expand Up @@ -139,15 +140,20 @@ impl Client {
.unwrap())
}

// TODO(support:v0.2): remove
m1sterc001guy marked this conversation as resolved.
Show resolved Hide resolved
pub async fn use_gateway(&self, gw: &super::gatewayd::Gatewayd) -> Result<()> {
let gateway_id = gw.gateway_id().await?;
cmd!(self, "switch-gateway", gateway_id.clone())
.run()
.await?;
info!(
"Using {name} gateway",
name = gw.ln.as_ref().unwrap().name()
);
let fedimint_cli_version = crate::util::FedimintCli::version_or_default().await;
if VersionReq::parse("<0.3.0-alpha")?.matches(&fedimint_cli_version) {
let gateway_id = gw.gateway_id().await?;
cmd!(self, "switch-gateway", gateway_id.clone())
.run()
.await?;
info!(
"Using {name} gateway",
name = gw.ln.as_ref().unwrap().name()
);
}

Ok(())
}

Expand Down Expand Up @@ -386,8 +392,15 @@ impl Federation {
}

pub async fn await_gateways_registered(&self) -> Result<()> {
let fedimint_cli_version = crate::util::FedimintCli::version_or_default().await;
let command = if VersionReq::parse("<0.3.0-alpha")?.matches(&fedimint_cli_version) {
"list-gateways"
} else {
"update-gateway-cache"
};

poll("gateways registered", None, || async {
let num_gateways = cmd!(self.client, "list-gateways")
let num_gateways = cmd!(self.client, command)
.out_json()
.await
.map_err(ControlFlow::Continue)?
Expand Down
168 changes: 120 additions & 48 deletions devimint/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use clap::Subcommand;
use cln_rpc::primitives::{Amount as ClnRpcAmount, AmountOrAny};
use fedimint_cli::LnInvoiceResponse;
use fedimint_core::encoding::Decodable;
use fedimint_core::Amount;
use fedimint_logging::LOG_DEVIMINT;
use ln_gateway::rpc::GatewayInfo;
use semver::VersionReq;
Expand Down Expand Up @@ -122,6 +123,8 @@ pub async fn latency_tests(dev_fed: DevFed, r#type: LatencyTest) -> Result<()> {
// LN operations take longer, we need less iterations
let iterations = 20;

let cln_gw_id = gw_cln.gateway_id().await?;

match r#type {
LatencyTest::Reissue => {
info!("Testing latency of reissue");
Expand Down Expand Up @@ -165,7 +168,7 @@ pub async fn latency_tests(dev_fed: DevFed, r#type: LatencyTest) -> Result<()> {
let invoice = add_invoice.payment_request;
let payment_hash = add_invoice.r_hash;
let start_time = Instant::now();
cmd!(client, "ln-pay", invoice).run().await?;
ln_pay(&client, invoice, cln_gw_id.clone(), false).await?;
let invoice_status = lnd
.lightning_client_lock()
.await?
Expand Down Expand Up @@ -204,20 +207,17 @@ pub async fn latency_tests(dev_fed: DevFed, r#type: LatencyTest) -> Result<()> {
.into_inner();

let invoice = add_invoice.payment_request;
cmd!(client, "ln-pay", invoice).run().await?;
ln_pay(&client, invoice, cln_gw_id.clone(), false).await?;

for _ in 0..iterations {
let invoice = cmd!(
client,
"ln-invoice",
"--amount=100000msat",
"--description=incoming-over-lnd-gw"
let invoice = ln_invoice(
&client,
Amount::from_msats(100000),
"latency-over-cln-gw".to_string(),
cln_gw_id.clone(),
)
.out_json()
.await?["invoice"]
.as_str()
.context("invoice must be string")?
.to_owned();
.await?
.invoice;

let start_time = Instant::now();
let payment = lnd
Expand Down Expand Up @@ -363,6 +363,8 @@ pub async fn cli_tests(dev_fed: DevFed) -> Result<()> {

let client = fed.new_joined_client("cli-tests-client").await?;
client.use_gateway(&gw_cln).await?;
let cln_gw_id = gw_cln.gateway_id().await?;
let lnd_gw_id = gw_lnd.gateway_id().await?;

cmd!(
client,
Expand Down Expand Up @@ -634,7 +636,7 @@ pub async fn cli_tests(dev_fed: DevFed) -> Result<()> {
// finish this payment at the end
info!("Testing fedimint-cli pays LND HOLD invoice via CLN gateway");
let (hold_invoice_preimage, hold_invoice_hash, hold_invoice_operation_id) =
start_hold_invoice_payment(&client, &gw_cln, &lnd).await?;
start_hold_invoice_payment(&client, &gw_cln, cln_gw_id.clone(), &lnd).await?;

// OUTGOING: fedimint-cli pays LND via CLN gateway
info!("Testing fedimint-cli pays LND via CLN gateway");
Expand All @@ -657,7 +659,7 @@ pub async fn cli_tests(dev_fed: DevFed) -> Result<()> {
.into_inner();
let invoice = add_invoice.payment_request;
let payment_hash = add_invoice.r_hash;
cmd!(client, "ln-pay", invoice).run().await?;
ln_pay(&client, invoice, cln_gw_id.clone(), false).await?;

let invoice_status = lnd
.lightning_client_lock()
Expand Down Expand Up @@ -691,15 +693,13 @@ pub async fn cli_tests(dev_fed: DevFed) -> Result<()> {
final_cln_outgoing_gateway_balance - initial_cln_gateway_balance
);

let ln_response_val = cmd!(
client,
"ln-invoice",
"--amount=1100000msat",
"--description='incoming-over-cln-gw'"
let ln_invoice_response = ln_invoice(
&client,
Amount::from_msats(1100000),
"incoming-over-cln-gw".to_string(),
cln_gw_id.clone(),
)
.out_json()
.await?;
let ln_invoice_response: LnInvoiceResponse = serde_json::from_value(ln_response_val)?;
let invoice = ln_invoice_response.invoice;
let payment = lnd
.lightning_client_lock()
Expand Down Expand Up @@ -774,7 +774,7 @@ pub async fn cli_tests(dev_fed: DevFed) -> Result<()> {
.await?
.bolt11;
tokio::try_join!(cln.await_block_processing(), lnd.await_block_processing())?;
cmd!(client, "ln-pay", invoice.clone()).run().await?;
ln_pay(&client, invoice.clone(), lnd_gw_id.clone(), false).await?;
let fed_id = fed.calculate_federation_id().await;

let invoice_status = cln
Expand Down Expand Up @@ -809,16 +809,14 @@ pub async fn cli_tests(dev_fed: DevFed) -> Result<()> {

// INCOMING: fedimint-cli receives from CLN via LND gateway
info!("Testing incoming payment from CLN to client via LND gateway");
let ln_response_val = cmd!(
client,
"ln-invoice",
"--amount=1300000msat",
"--description='incoming-over-lnd-gw'"
let recv = ln_invoice(
&client,
Amount::from_msats(1300000),
"incoming-over-lnd-gw".to_string(),
lnd_gw_id,
)
.out_json()
.await?;
let ln_invoice_response: LnInvoiceResponse = serde_json::from_value(ln_response_val)?;
let invoice = ln_invoice_response.invoice;
let invoice = recv.invoice;
let invoice_status = cln
.request(cln_rpc::model::requests::PayRequest {
bolt11: invoice,
Expand All @@ -843,7 +841,7 @@ pub async fn cli_tests(dev_fed: DevFed) -> Result<()> {

// Receive the ecash notes
info!("Testing receiving ecash notes");
let operation_id = ln_invoice_response.operation_id;
let operation_id = recv.operation_id;
cmd!(client, "await-invoice", operation_id).run().await?;

// Assert balances changed by 1_300_000 msat
Expand Down Expand Up @@ -939,6 +937,7 @@ pub async fn cli_tests(dev_fed: DevFed) -> Result<()> {
pub async fn start_hold_invoice_payment(
client: &Client,
gw_cln: &Gatewayd,
gw_cln_id: String,
lnd: &Lnd,
) -> anyhow::Result<([u8; 32], cln_rpc::primitives::Sha256, String)> {
client.use_gateway(gw_cln).await?;
Expand All @@ -960,12 +959,7 @@ pub async fn start_hold_invoice_payment(
.await?
.into_inner()
.payment_request;
let operation_id = cmd!(client, "ln-pay", payment_request, "--finish-in-background")
.out_json()
.await?["operation_id"]
.as_str()
.context("missing operation id")?
.to_owned();
let operation_id = ln_pay(client, payment_request, gw_cln_id, true).await?;
Ok((preimage, hash, operation_id))
}

Expand Down Expand Up @@ -1427,6 +1421,7 @@ pub async fn gw_reboot_test(dev_fed: DevFed, process_mgr: &ProcessManager) -> Re
let (cln_value, lnd_value) = tokio::try_join!(cln_cmd.out_json(), lnd_cmd.out_json())?;

// Drop references to cln and lnd gateways so the test can kill them
let cln_gateway_id = gw_cln.gateway_id().await?;
drop(gw_cln);
drop(gw_lnd);

Expand All @@ -1444,8 +1439,7 @@ pub async fn gw_reboot_test(dev_fed: DevFed, process_mgr: &ProcessManager) -> Re
.await?
.into_inner();
let invoice = add_invoice.payment_request;
cmd!(client, "ln-pay", invoice)
.run()
ln_pay(&client, invoice, cln_gateway_id, false)
.await
.expect_err("Expected ln-pay to return error because the gateway is not online");
let new_client_balance = client.balance().await?;
Expand Down Expand Up @@ -1525,18 +1519,16 @@ pub async fn do_try_create_and_pay_invoice(
)
.await?;

client.use_gateway(gw).await?;
tracing::info!("Creating invoice....");
let ln_response_val = cmd!(
client.use_gateway(gw).await?;
let invoice = ln_invoice(
client,
"ln-invoice",
"--amount=1000msat",
"--description='incoming-over-cln-gw'"
Amount::from_msats(1000),
"incoming-over-cln-gw".to_string(),
gw.gateway_id().await?,
)
.out_json()
.await?;
let ln_invoice_response: LnInvoiceResponse = serde_json::from_value(ln_response_val)?;
let invoice = ln_invoice_response.invoice;
.await?
.invoice;

match gw.ln.as_ref() {
Some(LightningNode::Cln(_cln)) => {
Expand Down Expand Up @@ -1598,6 +1590,86 @@ pub async fn do_try_create_and_pay_invoice(
Ok(())
}

async fn ln_pay(
client: &Client,
invoice: String,
gw_id: String,
finish_in_background: bool,
) -> anyhow::Result<String> {
let fedimint_cli_version = crate::util::FedimintCli::version_or_default().await;

// TODO(support:v0.2): 0.3 removed the active gateway concept and requires a
// `gateway-id` parameter for lightning sends
let value = if VersionReq::parse("<0.3.0-alpha")?.matches(&fedimint_cli_version) {
if finish_in_background {
cmd!(client, "ln-pay", invoice, "--finish-in-background",)
.out_json()
.await?
} else {
cmd!(client, "ln-pay", invoice,).out_json().await?
}
} else if finish_in_background {
cmd!(
client,
"ln-pay",
invoice,
"--finish-in-background",
"--gateway-id",
gw_id,
)
.out_json()
.await?
} else {
cmd!(client, "ln-pay", invoice, "--gateway-id", gw_id,)
.out_json()
.await?
};

let operation_id = value["operation_id"]
.as_str()
.expect("missing operation id")
.to_string();
Ok(operation_id)
}

async fn ln_invoice(
client: &Client,
amount: Amount,
description: String,
gw_id: String,
) -> anyhow::Result<LnInvoiceResponse> {
let fedimint_cli_version = crate::util::FedimintCli::version_or_default().await;
// TODO(support:v0.2): 0.3 removed the active gateway concept and requires a
// `gateway-id` parameter for lightning receives
let ln_response_val = if VersionReq::parse("<0.3.0-alpha")?.matches(&fedimint_cli_version) {
cmd!(
client,
"ln-invoice",
"--amount",
amount.msats,
format!("--description='{description}'"),
)
.out_json()
.await?
} else {
cmd!(
client,
"ln-invoice",
"--amount",
amount.msats,
format!("--description='{description}'"),
"--gateway-id",
gw_id,
)
.out_json()
.await?
};

let ln_invoice_response: LnInvoiceResponse = serde_json::from_value(ln_response_val)?;

Ok(ln_invoice_response)
}

pub async fn reconnect_test(dev_fed: DevFed, process_mgr: &ProcessManager) -> Result<()> {
log_binary_versions().await?;
#[allow(unused_variables)]
Expand Down
Loading
Loading