Skip to content

Commit

Permalink
merge main
Browse files Browse the repository at this point in the history
  • Loading branch information
chenyukang committed Nov 25, 2024
2 parents d073471 + 89c2483 commit 07dc1f4
Show file tree
Hide file tree
Showing 47 changed files with 1,429 additions and 622 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
tests/nodes/.ports
/coverage-report
/*.info
.vscode
5 changes: 3 additions & 2 deletions src/cch/actor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::fiber::hash_algorithm::HashAlgorithm;
use crate::fiber::types::{Hash256, RemoveTlcFulfill, RemoveTlcReason};
use crate::fiber::{NetworkActorCommand, NetworkActorMessage};
use crate::invoice::Currency;
use crate::now_timestamp;
use crate::now_timestamp_as_millis_u64;

use super::error::CchDbError;
use super::{CchConfig, CchError, CchOrderStatus, CchOrdersDb, ReceiveBTCOrder, SendBTCOrder};
Expand Down Expand Up @@ -592,7 +592,8 @@ impl CchActor {
payment_hash: Some(
Hash256::from_str(&order.payment_hash).expect("parse Hash256"),
),
expiry: now_timestamp() + self.config.ckb_final_tlc_expiry_delta,
expiry: now_timestamp_as_millis_u64()
+ self.config.ckb_final_tlc_expiry_delta,
hash_algorithm: HashAlgorithm::Sha256,
onion_packet: vec![],
previous_tlc: None,
Expand Down
640 changes: 392 additions & 248 deletions src/fiber/channel.rs

Large diffs are not rendered by default.

38 changes: 17 additions & 21 deletions src/fiber/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,29 @@ use std::{fs, path::PathBuf, str::FromStr};
use tentacle::secio::{PublicKey, SecioKeyPair};

pub const CKB_SHANNONS: u64 = 100_000_000; // 1 CKB = 10 ^ 8 shannons
pub const DEFAULT_MIN_INBOUND_LIQUIDITY: u64 = 100 * CKB_SHANNONS; // 100 CKB for minimal inbound liquidity
pub const DEFAULT_MIN_SHUTDOWN_FEE: u64 = CKB_SHANNONS; // 1 CKB prepared for shutdown transaction fee
pub const MIN_OCCUPIED_CAPACITY: u64 = 61 * CKB_SHANNONS; // 61 CKB for occupied capacity
pub const MIN_UDT_OCCUPIED_CAPACITY: u64 = 142 * CKB_SHANNONS; // 142 CKB for UDT occupied capacity
pub const DEFAULT_MIN_SHUTDOWN_FEE: u64 = 1 * CKB_SHANNONS; // 1 CKB prepared for shutdown transaction fee

/// By default, listen to any tcp port allocated by the kernel.
pub const DEFAULT_LISTENING_ADDR: &str = "/ip4/0.0.0.0/tcp/0";

/// 62 CKB minimal channel amount, at any time a partner should keep at least
/// `DEFAULT_CHANNEL_MINIMAL_CKB_AMOUNT` CKB in the channel,
/// to make sure he can build a valid shutdown transaction and pay proper fee.
pub const DEFAULT_CHANNEL_MINIMAL_CKB_AMOUNT: u64 =
MIN_OCCUPIED_CAPACITY + DEFAULT_MIN_SHUTDOWN_FEE;
const MIN_OCCUPIED_CAPACITY: u64 = 61 * CKB_SHANNONS; // 61 CKB for occupied capacity

/// 143 CKB for minimal UDT amount
pub const DEFAULT_UDT_MINIMAL_CKB_AMOUNT: u64 =
MIN_UDT_OCCUPIED_CAPACITY + DEFAULT_MIN_SHUTDOWN_FEE;
/// Default ckb funding amount when auto accepting an open channel request.
pub const DEFAULT_AUTO_ACCEPT_CHANNEL_CKB_FUNDING_AMOUNT: u64 =
MIN_OCCUPIED_CAPACITY + DEFAULT_MIN_SHUTDOWN_FEE;

/// 162 CKB to open a channel which maybe automatically acceptted.
/// 100 CKB for minimal inbound liquidity, 61 CKB for occupied capacity, 1 CKB for shutdown fee
/// The other party may auto accept the channel if the amount is greater than this.
pub const DEFAULT_CHANNEL_MIN_AUTO_CKB_AMOUNT: u64 =
DEFAULT_MIN_INBOUND_LIQUIDITY + MIN_OCCUPIED_CAPACITY + DEFAULT_MIN_SHUTDOWN_FEE;
/// Default minimum ckb funding amount for auto accepting an open channel request.
pub const DEFAULT_OPEN_CHANNEL_AUTO_ACCEPT_MIN_CKB_FUNDING_AMOUNT: u64 = 100 * CKB_SHANNONS;

/// The expiry delta to forward a tlc, in milliseconds, default to 1 day.
pub const DEFAULT_TLC_EXPIRY_DELTA: u64 = 24 * 60 * 60 * 1000;

/// The minimal expiry delta to forward a tlc, in milliseconds. 15 minutes.
pub const MIN_TLC_EXPIRY_DELTA: u64 = 15 * 60 * 1000; // 15 minutes

/// The maximum expiry delta for a payment, in milliseconds. 2 days
pub const MAX_PAYMENT_TLC_EXPIRY_LIMIT: u64 = 2 * 24 * 60 * 60 * 1000; // 2 days

/// The minimal value of a tlc. 0 means no minimal value.
pub const DEFAULT_TLC_MIN_VALUE: u128 = 0;

Expand Down Expand Up @@ -113,12 +109,12 @@ pub struct FiberConfig {
#[arg(name = "FIBER_SCRIPTS", long = "fiber-scripts", env, value_parser, num_args = 0.., value_delimiter = ',')]
pub scripts: Vec<FiberScript>,

/// minimum ckb funding amount for auto accepting an open channel requests, aunit: shannons [default: 16200000000 shannons]
/// minimum ckb funding amount for auto accepting an open channel requests, unit: shannons [default: 10000000000 shannons]
#[arg(
name = "FIBER_OPEN_CHANNEL_AUTO_ACCEPT_MIN_CKB_FUNDING_AMOUNT",
long = "fiber-open-channel-auto-accept-min-ckb-funding-amount",
env,
help = "minimum ckb funding amount for auto accepting an open channel requests, unit: shannons [default: 16200000000 shannons]"
help = "minimum ckb funding amount for auto accepting an open channel requests, unit: shannons [default: 10000000000 shannons]"
)]
pub open_channel_auto_accept_min_ckb_funding_amount: Option<u64>,
/// whether to accept open channel requests with ckb funding amount automatically, unit: shannons [default: 6200000000 shannons], if this is set to zero, it means to disable auto accept
Expand Down Expand Up @@ -318,12 +314,12 @@ impl FiberConfig {

pub fn open_channel_auto_accept_min_ckb_funding_amount(&self) -> u64 {
self.open_channel_auto_accept_min_ckb_funding_amount
.unwrap_or(DEFAULT_CHANNEL_MIN_AUTO_CKB_AMOUNT)
.unwrap_or(DEFAULT_OPEN_CHANNEL_AUTO_ACCEPT_MIN_CKB_FUNDING_AMOUNT)
}

pub fn auto_accept_channel_ckb_funding_amount(&self) -> u64 {
self.auto_accept_channel_ckb_funding_amount
.unwrap_or(DEFAULT_CHANNEL_MINIMAL_CKB_AMOUNT)
.unwrap_or(DEFAULT_AUTO_ACCEPT_CHANNEL_CKB_FUNDING_AMOUNT)
}

pub fn tlc_expiry_delta(&self) -> u64 {
Expand Down
9 changes: 0 additions & 9 deletions src/fiber/fee.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use super::channel::FUNDING_CELL_WITNESS_LEN;
use super::config::{DEFAULT_CHANNEL_MINIMAL_CKB_AMOUNT, DEFAULT_UDT_MINIMAL_CKB_AMOUNT};
use crate::ckb::contracts::{get_cell_deps, get_script_by_contract, Contract};
use ckb_types::core::TransactionBuilder;
use ckb_types::packed::{Bytes, Script};
Expand All @@ -12,14 +11,6 @@ use ckb_types::{
use molecule::prelude::Entity;
use tracing::debug;

pub(crate) fn default_minimal_ckb_amount(is_udt: bool) -> u64 {
if is_udt {
DEFAULT_UDT_MINIMAL_CKB_AMOUNT
} else {
DEFAULT_CHANNEL_MINIMAL_CKB_AMOUNT
}
}

fn commitment_tx_size(udt_type_script: &Option<Script>) -> usize {
// when there is pending htlcs, the commitment lock args will be 56 bytes, otherwise 46 bytes.
// to simplify the calculation, we use hardcoded 56 bytes here.
Expand Down
66 changes: 39 additions & 27 deletions src/fiber/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::fiber::path::NodeHeapElement;
use crate::fiber::serde_utils::EntityHex;
use crate::fiber::types::PaymentHopData;
use crate::invoice::CkbInvoice;
use crate::now_timestamp;
use crate::now_timestamp_as_millis_u64;
use ckb_jsonrpc_types::JsonBytes;
use ckb_types::packed::{OutPoint, Script};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -136,11 +136,11 @@ pub struct ChannelUpdateInfo {
/// Whether the channel can be currently used for payments (in this one direction).
pub enabled: bool,
/// The difference in htlc expiry values that you must have when routing through this channel (in milliseconds).
pub htlc_expiry_delta: u64,
pub tlc_expiry_delta: u64,
/// The minimum value, which must be relayed to the next hop via the channel
pub htlc_minimum_value: u128,
pub tlc_minimum_value: u128,
/// The maximum value which may be relayed to the next hop via the channel.
pub htlc_maximum_value: u128,
pub tlc_maximum_value: u128,
pub fee_rate: u64,
/// Most recent update for the channel received from the network
/// Mostly redundant with the data we store in fields explicitly.
Expand Down Expand Up @@ -431,9 +431,9 @@ where
.expect("Duration since unix epoch")
.as_millis() as u64,
enabled: !disabled,
htlc_expiry_delta: update.tlc_expiry_delta,
htlc_minimum_value: update.tlc_minimum_value,
htlc_maximum_value: update.tlc_maximum_value,
tlc_expiry_delta: update.tlc_expiry_delta,
tlc_minimum_value: update.tlc_minimum_value,
tlc_maximum_value: update.tlc_maximum_value,
fee_rate: update.tlc_fee_proportional_millionths as u64,
last_update_message: update.clone(),
});
Expand Down Expand Up @@ -547,6 +547,7 @@ where
let preimage = payment_data.preimage;
let payment_hash = payment_data.payment_hash;
let udt_type_script = payment_data.udt_type_script;
let final_tlc_expiry_delta = payment_data.final_tlc_expiry_delta;
let invoice = payment_data
.invoice
.map(|x| x.parse::<CkbInvoice>().expect("parse CKB invoice"));
Expand All @@ -563,7 +564,7 @@ where
let allow_self_payment = payment_data.allow_self_payment;
if source == target && !allow_self_payment {
return Err(PathFindError::PathFind(
"source and target are the same and allow_self_payment is not enable".to_string(),
"allow_self_payment is not enable, can not pay to self".to_string(),
));
}

Expand All @@ -573,13 +574,17 @@ where
amount,
payment_data.max_fee_amount,
udt_type_script,
final_tlc_expiry_delta,
payment_data.tlc_expiry_limit,
allow_self_payment,
)?;
assert!(!route.is_empty());

let mut current_amount = amount;
let mut current_expiry = 0;
let mut hops_data = vec![];
let current_time = now_timestamp_as_millis_u64();

for i in (0..route.len()).rev() {
let is_last = i == route.len() - 1;
let (next_hop, next_channel_outpoint) = if is_last {
Expand All @@ -591,7 +596,7 @@ where
)
};
let (fee, expiry) = if is_last {
(0, 0)
(0, current_time + final_tlc_expiry_delta)
} else {
let channel_info = self
.get_channel(&route[i].channel_outpoint)
Expand All @@ -601,7 +606,7 @@ where
.expect("channel_update is none");
let fee_rate = channel_update.fee_rate;
let fee = calculate_tlc_forward_fee(current_amount, fee_rate as u128);
let expiry = channel_update.htlc_expiry_delta;
let expiry = channel_update.tlc_expiry_delta;
(fee, expiry)
};

Expand All @@ -616,8 +621,8 @@ where
channel_outpoint: next_channel_outpoint,
preimage: if is_last { preimage } else { None },
});
current_amount += fee;
current_expiry += expiry;
current_amount += fee;
}
// Add the first hop as the instruction for the current node, so the logic for send HTLC can be reused.
hops_data.push(PaymentHopData {
Expand Down Expand Up @@ -653,6 +658,8 @@ where
amount: u128,
max_fee_amount: Option<u128>,
udt_type_script: Option<Script>,
fianl_tlc_expiry_delta: u64,
tlc_expiry_limit: u64,
allow_self: bool,
) -> Result<Vec<PathEdge>, PathFindError> {
let started_time = std::time::Instant::now();
Expand All @@ -679,7 +686,7 @@ where

if source == target && !allow_self {
return Err(PathFindError::PathFind(
"source and target are the same".to_string(),
"allow_self_payment is not enable, can not pay self".to_string(),
));
}

Expand All @@ -705,7 +712,7 @@ where
fee_charged: 0,
probability: 1.0,
next_hop: None,
incoming_htlc_expiry: 0,
incoming_tlc_expiry: fianl_tlc_expiry_delta,
});

while let Some(cur_hop) = nodes_heap.pop() {
Expand Down Expand Up @@ -742,22 +749,27 @@ where
}
}
// check to make sure the current hop can send the amount
// if `htlc_maximum_value` equals 0, it means there is no limit
// if `tlc_maximum_value` equals 0, it means there is no limit
if amount_to_send > channel_info.capacity()
|| (channel_update.htlc_maximum_value != 0
&& amount_to_send > channel_update.htlc_maximum_value)
|| (channel_update.tlc_maximum_value != 0
&& amount_to_send > channel_update.tlc_maximum_value)
{
continue;
}
if amount_to_send < channel_update.htlc_minimum_value {
if amount_to_send < channel_update.tlc_minimum_value {
continue;
}

let expiry_delta = if from == source {
0
} else {
channel_update.tlc_expiry_delta
};

let incoming_htlc_expiry = cur_hop.incoming_tlc_expiry + expiry_delta;
if incoming_htlc_expiry > tlc_expiry_limit {
continue;
}
let incoming_htlc_expiry = cur_hop.incoming_htlc_expiry
+ if from == source {
0
} else {
channel_update.htlc_expiry_delta
};

let probability = cur_hop.probability
* self.history.eval_probability(
Expand All @@ -772,7 +784,7 @@ where
continue;
}
let agg_weight =
self.edge_weight(amount_to_send, fee, channel_update.htlc_expiry_delta);
self.edge_weight(amount_to_send, fee, channel_update.tlc_expiry_delta);
let weight = cur_hop.weight + agg_weight;
let distance = self.calculate_distance_based_probability(probability, weight);

Expand All @@ -786,7 +798,7 @@ where
weight,
distance,
amount_received: amount_to_send,
incoming_htlc_expiry,
incoming_tlc_expiry: incoming_htlc_expiry,
fee_charged: fee,
probability,
next_hop: Some((cur_hop.node_id, channel_info.out_point())),
Expand Down Expand Up @@ -949,7 +961,7 @@ pub struct PaymentSession {

impl PaymentSession {
pub fn new(request: SendPaymentData, try_limit: u32) -> Self {
let now = now_timestamp();
let now = now_timestamp_as_millis_u64();
Self {
request,
retried_times: 0,
Expand All @@ -970,7 +982,7 @@ impl PaymentSession {

fn set_status(&mut self, status: PaymentSessionStatus) {
self.status = status;
self.last_updated_at = now_timestamp();
self.last_updated_at = now_timestamp_as_millis_u64();
}

pub fn set_inflight_status(&mut self, channel_outpoint: OutPoint, tlc_id: u64) {
Expand Down
4 changes: 3 additions & 1 deletion src/fiber/graph_syncer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use tracing::{debug, error};

use anyhow::anyhow;

use crate::now_timestamp_as_millis_u64;

use super::{
network::GraphSyncerExitStatus, NetworkActorCommand, NetworkActorEvent, NetworkActorMessage,
ASSUME_NETWORK_ACTOR_ALIVE,
Expand Down Expand Up @@ -56,7 +58,7 @@ impl GraphSyncer {
ending_height: u64,
starting_time: u64,
) -> Self {
let now = std::time::UNIX_EPOCH.elapsed().unwrap().as_millis() as u64;
let now = now_timestamp_as_millis_u64();
Self {
network,
peer_id,
Expand Down
Loading

0 comments on commit 07dc1f4

Please sign in to comment.