Skip to content

Commit

Permalink
Amount interface for limits (#401)
Browse files Browse the repository at this point in the history
  • Loading branch information
andrei-21 authored May 31, 2023
1 parent 3af9cb7 commit a3217b5
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 77 deletions.
12 changes: 5 additions & 7 deletions eel/examples/eel-node/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,16 +127,14 @@ fn lsp_fee(node: &LightningNode) {
fn payment_amount_limits(node: &LightningNode) {
let limits = node.get_payment_amount_limits().unwrap();

println!(" Beta maximum receive: {} sats", limits.max_receive_sat);
println!(" Beta maximum receive: {} msats", limits.max_receive_msat);

match limits.liquidity_limit {
LiquidityLimit::MinReceive { sat_amount } => {
println!(" Minimum payment amount: {sat_amount} sats. A setup fee will be charged.");
LiquidityLimit::MinReceive { amount_msat } => {
println!(" Minimum payment amount: {amount_msat} msats. A setup fee will be charged.");
}
LiquidityLimit::MaxFreeReceive { sat_amount } => {
println!(
" If you want to receive more than {sat_amount} sats, a setup fee will be charged."
);
LiquidityLimit::MaxFreeReceive { amount_msat } => {
println!(" If you want to receive more than {amount_msat} msats, a setup fee will be charged.");
}
LiquidityLimit::None => {}
}
Expand Down
11 changes: 4 additions & 7 deletions eel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ mod task_manager;
mod test_utils;
mod tx_broadcaster;
mod types;
pub mod utils;

use crate::async_runtime::AsyncRuntime;
use crate::config::{Config, TzConfig};
Expand All @@ -58,7 +57,6 @@ use crate::tx_broadcaster::TxBroadcaster;
use crate::types::{ChainMonitor, ChannelManager, PeerManager, RapidGossipSync, Router, TxSync};
use std::fs;

use crate::utils::{round_down_to_sat, round_up_to_sat};
use bitcoin::hashes::hex::ToHex;
pub use bitcoin::Network;
use cipher::consts::U32;
Expand Down Expand Up @@ -628,13 +626,12 @@ impl LightningNode {
}

pub fn get_payment_amount_limits(&self) -> Result<PaymentAmountLimits> {
let lsp_min_fee = round_up_to_sat(self.query_lsp_fee()?.channel_minimum_fee_msat);
let inbound_capacity =
round_down_to_sat(self.get_node_info().channels_info.inbound_capacity_msat);
let lsp_min_fee_msat = self.query_lsp_fee()?.channel_minimum_fee_msat;
let inbound_capacity_msat = self.get_node_info().channels_info.inbound_capacity_msat;

Ok(PaymentAmountLimits::calculate(
inbound_capacity,
lsp_min_fee,
inbound_capacity_msat,
lsp_min_fee_msat,
))
}

Expand Down
22 changes: 11 additions & 11 deletions eel/src/limits.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
const MAX_RECEIVE_AMOUNT_BETA_SAT: u64 = 1_000_000;
const MAX_RECEIVE_AMOUNT_BETA_MSAT: u64 = 1_000_000_000;
const MIN_RECEIVE_MULTIPLIER: u64 = 2; // Minimum receive = mutliple of setup fees

#[derive(PartialEq, Eq, Debug)]
pub struct PaymentAmountLimits {
pub max_receive_sat: u64,
pub max_receive_msat: u64,
pub liquidity_limit: LiquidityLimit,
}

#[derive(PartialEq, Eq, Debug)]
pub enum LiquidityLimit {
None,
MaxFreeReceive { sat_amount: u64 },
MinReceive { sat_amount: u64 },
MaxFreeReceive { amount_msat: u64 },
MinReceive { amount_msat: u64 },
}

impl PaymentAmountLimits {
pub fn calculate(inbound_capacity: u64, lsp_min_fee: u64) -> Self {
let min_receive_amount = lsp_min_fee * MIN_RECEIVE_MULTIPLIER;
pub fn calculate(inbound_capacity_msat: u64, lsp_min_fee: u64) -> Self {
let min_receive_msat = lsp_min_fee * MIN_RECEIVE_MULTIPLIER;

let liquidity_limit = if inbound_capacity < min_receive_amount {
let liquidity_limit = if inbound_capacity_msat < min_receive_msat {
LiquidityLimit::MinReceive {
sat_amount: min_receive_amount,
amount_msat: min_receive_msat,
}
} else if inbound_capacity < MAX_RECEIVE_AMOUNT_BETA_SAT {
} else if inbound_capacity_msat < MAX_RECEIVE_AMOUNT_BETA_MSAT {
LiquidityLimit::MaxFreeReceive {
sat_amount: inbound_capacity,
amount_msat: inbound_capacity_msat,
}
} else {
LiquidityLimit::None
};

PaymentAmountLimits {
max_receive_sat: MAX_RECEIVE_AMOUNT_BETA_SAT,
max_receive_msat: MAX_RECEIVE_AMOUNT_BETA_MSAT,
liquidity_limit,
}
}
Expand Down
30 changes: 0 additions & 30 deletions eel/src/utils.rs

This file was deleted.

14 changes: 7 additions & 7 deletions eel/tests/receiving_payments_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ mod setup_env;
mod receiving_payments_test {
use bitcoin::hashes::hex::ToHex;
use eel::limits::LiquidityLimit;
use eel::utils::round_down_to_sat;
use eel::LightningNode;
use log::info;
use serial_test::file_serial;
Expand Down Expand Up @@ -296,30 +295,31 @@ mod receiving_payments_test {
fn assert_low_inbound_capacity(node: &LightningNode) {
let limits = node.get_payment_amount_limits().unwrap();

assert_eq!(limits.max_receive_sat, 1_000_000);
assert_eq!(limits.max_receive_msat, 1_000_000_000);
assert_eq!(
limits.liquidity_limit,
LiquidityLimit::MinReceive { sat_amount: 4_000 },
LiquidityLimit::MinReceive {
amount_msat: 4_000_000
},
);
}

fn assert_moderate_inbound_capacity(node: &LightningNode, inbound_capacity_msat: u64) {
let limits = node.get_payment_amount_limits().unwrap();
let inbound_capacity = round_down_to_sat(inbound_capacity_msat);

assert_eq!(limits.max_receive_sat, 1_000_000);
assert_eq!(limits.max_receive_msat, 1_000_000_000);
assert_eq!(
limits.liquidity_limit,
LiquidityLimit::MaxFreeReceive {
sat_amount: inbound_capacity
amount_msat: inbound_capacity_msat
},
);
}

fn assert_high_inbound_capacity(node: &LightningNode) {
let limits = node.get_payment_amount_limits().unwrap();

assert_eq!(limits.max_receive_sat, 1_000_000);
assert_eq!(limits.max_receive_msat, 1_000_000_000);
assert_eq!(limits.liquidity_limit, LiquidityLimit::None);
}
}
19 changes: 13 additions & 6 deletions examples/3l-node/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ use bitcoin::secp256k1::PublicKey;
use chrono::offset::FixedOffset;
use chrono::{DateTime, Utc};
use colored::Colorize;
use eel::limits::LiquidityLimit;
use rustyline::config::{Builder, CompletionType};
use rustyline::error::ReadlineError;
use rustyline::history::DefaultHistory;
use rustyline::Editor;
use std::collections::HashSet;
use std::path::Path;
use uniffi_lipalightninglib::LiquidityLimit;

use crate::LightningNode;

Expand Down Expand Up @@ -232,15 +232,22 @@ fn calculate_lsp_fee(
fn payment_amount_limits(node: &LightningNode) {
let limits = node.get_payment_amount_limits().unwrap();

println!(" Beta maximum receive: {} SAT", limits.max_receive_sat);
println!(
" Beta maximum receive: {}",
amount_to_string(limits.max_receive)
);

match limits.liquidity_limit {
LiquidityLimit::MinReceive { sat_amount } => {
println!(" Minimum payment amount: {sat_amount} SAT. A setup fee will be charged.");
LiquidityLimit::MinReceive { amount } => {
println!(
" Minimum payment amount: {}. A setup fee will be charged.",
amount_to_string(amount)
);
}
LiquidityLimit::MaxFreeReceive { sat_amount } => {
LiquidityLimit::MaxFreeReceive { amount } => {
println!(
" If you want to receive more than {sat_amount} SAT, a setup fee will be charged."
" If you want to receive more than {}, a setup fee will be charged.",
amount_to_string(amount)
);
}
LiquidityLimit::None => {}
Expand Down
38 changes: 36 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ use eel::errors::{Error as LnError, Result, RuntimeErrorCode};
pub use eel::interfaces::ExchangeRate;
use eel::key_derivation::derive_key_pair_hex;
use eel::keys_manager::{generate_secret, mnemonic_to_secret, words_by_prefix};
use eel::limits::{LiquidityLimit, PaymentAmountLimits};
pub use eel::payment::FiatValues;
use eel::payment::{PaymentState, PaymentType, TzTime};
use eel::secret::Secret;
Expand All @@ -44,6 +43,17 @@ use std::sync::Arc;

const BACKEND_AUTH_DERIVATION_PATH: &str = "m/76738065'/0'/0";

pub struct PaymentAmountLimits {
pub max_receive: Amount,
pub liquidity_limit: LiquidityLimit,
}

pub enum LiquidityLimit {
None,
MaxFreeReceive { amount: Amount },
MinReceive { amount: Amount },
}

pub struct LspFee {
pub channel_minimum_fee: Amount,
pub channel_fee_permyriad: u64,
Expand Down Expand Up @@ -175,7 +185,10 @@ impl LightningNode {
}

pub fn get_payment_amount_limits(&self) -> Result<PaymentAmountLimits> {
self.core_node.get_payment_amount_limits()
let rate = self.get_exchange_rate();
self.core_node
.get_payment_amount_limits()
.map(|limits| to_limits(limits, &rate))
}

pub fn create_invoice(
Expand Down Expand Up @@ -324,4 +337,25 @@ fn to_payment(payment: eel::payment::Payment) -> Payment {
}
}

fn to_limits(
limits: eel::limits::PaymentAmountLimits,
rate: &Option<ExchangeRate>,
) -> PaymentAmountLimits {
let liquidity_limit = match limits.liquidity_limit {
eel::limits::LiquidityLimit::None => LiquidityLimit::None,
eel::limits::LiquidityLimit::MaxFreeReceive { amount_msat } => {
LiquidityLimit::MaxFreeReceive {
amount: amount_msat.to_amount_down(rate),
}
}
eel::limits::LiquidityLimit::MinReceive { amount_msat } => LiquidityLimit::MinReceive {
amount: amount_msat.to_amount_up(rate),
},
};
PaymentAmountLimits {
max_receive: limits.max_receive_msat.to_amount_down(rate),
liquidity_limit,
}
}

include!(concat!(env!("OUT_DIR"), "/lipalightninglib.uniffi.rs"));
14 changes: 7 additions & 7 deletions src/lipalightninglib.udl
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ interface LightningNode {
[Throws=LnError]
LspFee query_lsp_fee();

// Get the current limits for the amount (in SAT) that can be transferred in a single payment. Currently there are only limits for receiving payments.
// Get the current limits for the amount that can be transferred in a single payment. Currently there are only limits for receiving payments.
// The limits (partly) depend on the channel situation of the node, so it should be called again every time the user is about to receive a payment.
// The limits stay the same regardless of what amount wants to receive (= no changes while he's typing the amount)
[Throws=LnError]
Expand Down Expand Up @@ -235,15 +235,15 @@ dictionary LspFee {
};

dictionary PaymentAmountLimits {
u64 max_receive_sat; // Hard limit: The maximum sat amount a user is allowed to receive per payment
Amount max_receive; // Hard limit: The maximum amount a user is allowed to receive per payment
LiquidityLimit liquidity_limit;
};

[Enum]
interface LiquidityLimit {
None(); // inbound capacity >= max_receive_sat
MaxFreeReceive(u64 sat_amount); // Soft limit: The maximum sat amount a user can receive without being charged a setup fee
MinReceive(u64 sat_amount); // Hard limit: The minimum sat amount a user must receive with the next payment
None(); // inbound capacity >= max_receive
MaxFreeReceive(Amount amount); // Soft limit: The maximum amount a user can receive without being charged a setup fee
MinReceive(Amount amount); // Hard limit: The minimum amount a user must receive with the next payment
// If this limit is provided, that means a setup fee will be charged for the incoming payment
};

Expand Down Expand Up @@ -278,10 +278,10 @@ dictionary Payment {
// it is possible that a hex hash of the description is provided instead, but that is uncommon.
string? preimage; // Hex representation of the preimage. Will only be present on successful payments.
Amount? network_fees; // Routing fees paid in an `Sending` payment. Will only be present if payment was successful.
// The cost of sending a payment is `amount_msat` + `network_fees_msat`
// The cost of sending a payment is `amount` + `network_fees`
Amount? lsp_fees; // LSP fees paid in a `Receiving` payment. Will never be present for `Sending` payments but might be 0 for `Receiving` payments.
// The amount is only paid if successful.
// The value that is received in practice is given by `amount_msat` - `lsp_fees_msat`
// The value that is received in practice is given by `amount` - `lsp_fees`
string metadata;
};

Expand Down

0 comments on commit a3217b5

Please sign in to comment.