Skip to content

Commit

Permalink
Merge pull request fedimint#6270 from m1sterc001guy/gateway_cli_refactor
Browse files Browse the repository at this point in the history
refactor: Gateway CLI improvements
  • Loading branch information
dpc authored Nov 7, 2024
2 parents 01220d5 + 2f2e185 commit 95c17b4
Show file tree
Hide file tree
Showing 23 changed files with 326 additions and 360 deletions.
11 changes: 5 additions & 6 deletions devimint/src/federation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -754,12 +754,10 @@ impl Federation {
self.bitcoind.mine_blocks(21).await?;
try_join_all(gateways.into_iter().map(|gw| {
poll("gateway pegin", || async {
let gateway_balance = cmd!(gw, "balance", "--federation-id={fed_id}")
.out_json()
let gateway_balance = gw
.ecash_balance(fed_id.clone())
.await
.map_err(ControlFlow::Continue)?
.as_u64()
.unwrap();
.map_err(ControlFlow::Continue)?;
poll_eq!(gateway_balance, amount * 1000)
})
}))
Expand Down Expand Up @@ -791,7 +789,8 @@ impl Federation {
let pegout_address = self.bitcoind.get_new_address().await?;
let value = cmd!(
gw,
"withdraw",
"ecash",
"pegout",
"--federation-id",
fed_id,
"--amount",
Expand Down
21 changes: 11 additions & 10 deletions devimint/src/gatewayd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ impl Gatewayd {

pub async fn backup_to_fed(&self, fed: &Federation) -> Result<()> {
let federation_id = fed.calculate_federation_id();
cmd!(self, "backup", "--federation-id", federation_id)
cmd!(self, "ecash", "backup", "--federation-id", federation_id)
.run()
.await?;
Ok(())
Expand All @@ -270,7 +270,7 @@ impl Gatewayd {
}

pub async fn get_pegin_addr(&self, fed_id: &str) -> Result<String> {
Ok(cmd!(self, "address", "--federation-id={fed_id}")
Ok(cmd!(self, "ecash", "pegin", "--federation-id={fed_id}")
.out_json()
.await?
.as_str()
Expand All @@ -285,9 +285,7 @@ impl Gatewayd {
.out_string()
.await?
} else {
cmd!(self, "lightning", "get-ln-onchain-address")
.out_string()
.await?
cmd!(self, "onchain", "address").out_string().await?
};

Ok(address)
Expand Down Expand Up @@ -331,7 +329,8 @@ impl Gatewayd {
pub async fn send_ecash(&self, federation_id: String, amount_msats: u64) -> Result<String> {
let value = cmd!(
self,
"spend-ecash",
"ecash",
"send",
"--federation-id",
federation_id,
amount_msats
Expand All @@ -348,7 +347,9 @@ impl Gatewayd {
}

pub async fn receive_ecash(&self, ecash: String) -> Result<()> {
cmd!(self, "receive-ecash", "--notes", ecash).run().await?;
cmd!(self, "ecash", "receive", "--notes", ecash)
.run()
.await?;
Ok(())
}

Expand All @@ -370,7 +371,7 @@ impl Gatewayd {
Ok(ecash_balance)
}

pub async fn withdraw_onchain(
pub async fn send_onchain(
&self,
bitcoind: &Bitcoind,
amount: BitcoinAmountOrAll,
Expand All @@ -379,8 +380,8 @@ impl Gatewayd {
let withdraw_address = bitcoind.get_new_address().await?;
let value = cmd!(
self,
"lightning",
"withdraw-onchain",
"onchain",
"send",
"--address",
withdraw_address,
"--amount",
Expand Down
36 changes: 6 additions & 30 deletions devimint/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -880,11 +880,7 @@ pub async fn cli_tests(dev_fed: DevFed) -> Result<()> {
client.use_gateway(&gw_cln).await?;

let initial_client_balance = client.balance().await?;
let initial_cln_gateway_balance = cmd!(gw_cln, "balance", "--federation-id={fed_id}")
.out_json()
.await?
.as_u64()
.unwrap();
let initial_cln_gateway_balance = gw_cln.ecash_balance(fed_id.clone()).await?;
let (invoice, payment_hash) = lnd.invoice(1_200_000).await?;
ln_pay(&client, invoice.clone(), cln_gw_id.clone(), false).await?;
lnd.wait_bolt11_invoice(payment_hash).await?;
Expand All @@ -900,11 +896,7 @@ pub async fn cli_tests(dev_fed: DevFed) -> Result<()> {

// Assert balances changed by 1_200_000 msat (amount sent) + 0 msat (fee)
let final_cln_outgoing_client_balance = client.balance().await?;
let final_cln_outgoing_gateway_balance = cmd!(gw_cln, "balance", "--federation-id={fed_id}")
.out_json()
.await?
.as_u64()
.unwrap();
let final_cln_outgoing_gateway_balance = gw_cln.ecash_balance(fed_id.clone()).await?;

let expected_diff = 1_200_000;
anyhow::ensure!(
Expand Down Expand Up @@ -937,11 +929,7 @@ pub async fn cli_tests(dev_fed: DevFed) -> Result<()> {

// Assert balances changed by 1100000 msat
let final_cln_incoming_client_balance = client.balance().await?;
let final_cln_incoming_gateway_balance = cmd!(gw_cln, "balance", "--federation-id={fed_id}")
.out_json()
.await?
.as_u64()
.unwrap();
let final_cln_incoming_gateway_balance = gw_cln.ecash_balance(fed_id.clone()).await?;
anyhow::ensure!(
final_cln_incoming_client_balance - final_cln_outgoing_client_balance == 1_100_000,
"Client balance changed by {} on CLN incoming payment, expected 1100000",
Expand All @@ -959,11 +947,7 @@ pub async fn cli_tests(dev_fed: DevFed) -> Result<()> {

// OUTGOING: fedimint-cli pays CLN via LND gateaway
info!("Testing outgoing payment from client to CLN via LND gateway");
let initial_lnd_gateway_balance = cmd!(gw_lnd, "balance", "--federation-id={fed_id}")
.out_json()
.await?
.as_u64()
.unwrap();
let initial_lnd_gateway_balance = gw_lnd.ecash_balance(fed_id.clone()).await?;
let invoice = cln
.invoice(
2_000_000,
Expand All @@ -978,11 +962,7 @@ pub async fn cli_tests(dev_fed: DevFed) -> Result<()> {

// Assert balances changed by 2_000_000 msat (amount sent) + 0 msat (fee)
let final_lnd_outgoing_client_balance = client.balance().await?;
let final_lnd_outgoing_gateway_balance = cmd!(gw_lnd, "balance", "--federation-id={fed_id}")
.out_json()
.await?
.as_u64()
.unwrap();
let final_lnd_outgoing_gateway_balance = gw_lnd.ecash_balance(fed_id.clone()).await?;
anyhow::ensure!(
final_cln_incoming_client_balance - final_lnd_outgoing_client_balance == 2_000_000,
"Client balance changed by {} on LND outgoing payment, expected 2_000_000",
Expand Down Expand Up @@ -1015,11 +995,7 @@ pub async fn cli_tests(dev_fed: DevFed) -> Result<()> {

// Assert balances changed by 1_300_000 msat
let final_lnd_incoming_client_balance = client.balance().await?;
let final_lnd_incoming_gateway_balance = cmd!(gw_lnd, "balance", "--federation-id={fed_id}")
.out_json()
.await?
.as_u64()
.unwrap();
let final_lnd_incoming_gateway_balance = gw_lnd.ecash_balance(fed_id.clone()).await?;
anyhow::ensure!(
final_lnd_incoming_client_balance - final_lnd_outgoing_client_balance == 1_300_000,
"Client balance changed by {} on LND incoming payment, expected 1_300_000",
Expand Down
16 changes: 9 additions & 7 deletions fedimint-testing/src/ln.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ use ln_gateway::lightning::{
ChannelInfo, CloseChannelsWithPeerResponse, CreateInvoiceRequest, CreateInvoiceResponse,
GetBalancesResponse, GetLnOnchainAddressResponse, GetNodeInfoResponse, GetRouteHintsResponse,
ILnRpcClient, InterceptPaymentRequest, InterceptPaymentResponse, LightningRpcError,
OpenChannelResponse, PayInvoiceResponse, RouteHtlcStream, WithdrawOnchainResponse,
OpenChannelResponse, PayInvoiceResponse, RouteHtlcStream, SendOnchainResponse,
};
use ln_gateway::rpc::{CloseChannelsWithPeerPayload, OpenChannelPayload, WithdrawOnchainPayload};
use ln_gateway::rpc::{CloseChannelsWithPeerPayload, OpenChannelPayload, SendOnchainPayload};
use rand::rngs::OsRng;
use tokio::sync::mpsc;
use tracing::info;
Expand Down Expand Up @@ -271,10 +271,10 @@ impl ILnRpcClient for FakeLightningTest {
})
}

async fn withdraw_onchain(
async fn send_onchain(
&self,
_payload: WithdrawOnchainPayload,
) -> Result<WithdrawOnchainResponse, LightningRpcError> {
_payload: SendOnchainPayload,
) -> Result<SendOnchainResponse, LightningRpcError> {
Err(LightningRpcError::FailedToWithdrawOnchain {
failure_reason: "FakeLightningTest does not support withdrawing funds on-chain"
.to_string(),
Expand Down Expand Up @@ -308,8 +308,10 @@ impl ILnRpcClient for FakeLightningTest {
}

async fn get_balances(&self) -> Result<GetBalancesResponse, LightningRpcError> {
Err(LightningRpcError::FailedToGetBalances {
failure_reason: "FakeLightningTest does not support getting balances".to_string(),
Ok(GetBalancesResponse {
onchain_balance_sats: 0,
lightning_balance_msats: 0,
inbound_lightning_liquidity_msats: 0,
})
}
}
121 changes: 121 additions & 0 deletions gateway/cli/src/ecash_commands.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
use bitcoin::address::NetworkUnchecked;
use bitcoin::Address;
use clap::Subcommand;
use fedimint_core::config::FederationId;
use fedimint_core::{Amount, BitcoinAmountOrAll};
use fedimint_mint_client::OOBNotes;
use ln_gateway::rpc::rpc_client::GatewayRpcClient;
use ln_gateway::rpc::{
BackupPayload, DepositAddressPayload, ReceiveEcashPayload, SpendEcashPayload, WithdrawPayload,
};

use crate::print_response;

#[derive(Subcommand)]
pub enum EcashCommands {
/// Make a backup of snapshot of all e-cash.
Backup {
#[clap(long)]
federation_id: FederationId,
},
/// Generate a new peg-in address to a federation that the gateway can claim
/// e-cash for later.
Pegin {
#[clap(long)]
federation_id: FederationId,
},
/// Claim funds from a gateway federation to an on-chain address.
Pegout {
#[clap(long)]
federation_id: FederationId,
/// The amount to withdraw
#[clap(long)]
amount: BitcoinAmountOrAll,
/// The address to send the funds to
#[clap(long)]
address: Address<NetworkUnchecked>,
},
/// Send e-cash out of band
Send {
#[clap(long)]
federation_id: FederationId,
amount: Amount,
#[clap(long)]
allow_overpay: bool,
#[clap(long, default_value_t = 60 * 60 * 24 * 7)]
timeout: u64,
#[clap(long)]
include_invite: bool,
},
/// Receive e-cash out of band
Receive {
#[clap(long)]
notes: OOBNotes,
#[arg(long = "no-wait", action = clap::ArgAction::SetFalse)]
wait: bool,
},
}

impl EcashCommands {
pub async fn handle(
self,
create_client: impl Fn() -> GatewayRpcClient + Send + Sync,
) -> anyhow::Result<()> {
match self {
Self::Backup { federation_id } => {
create_client()
.backup(BackupPayload { federation_id })
.await?;
}
Self::Pegin { federation_id } => {
let response = create_client()
.get_deposit_address(DepositAddressPayload { federation_id })
.await?;

print_response(response);
}
Self::Pegout {
federation_id,
amount,
address,
} => {
let response = create_client()
.withdraw(WithdrawPayload {
federation_id,
amount,
address,
})
.await?;

print_response(response);
}
Self::Send {
federation_id,
amount,
allow_overpay,
timeout,
include_invite,
} => {
let response = create_client()
.spend_ecash(SpendEcashPayload {
federation_id,
amount,
allow_overpay,
timeout,
include_invite,
})
.await?;

print_response(response);
}
Self::Receive { notes, wait } => {
let response = create_client()
.receive_ecash(ReceiveEcashPayload { notes, wait })
.await?;
print_response(response);
}
}

Ok(())
}
}
Loading

0 comments on commit 95c17b4

Please sign in to comment.