From c6f2ea25e5a606702c38db063187c0b50b78b29d Mon Sep 17 00:00:00 2001 From: Impa10r Date: Thu, 11 Jul 2024 14:23:52 +0200 Subject: [PATCH 1/6] Ignore UnsettledBalance for liqPct --- .vscode/launch.json | 2 +- CHANGELOG.md | 6 +++++- cmd/psweb/handlers.go | 5 +++++ cmd/psweb/ln/lnd.go | 6 +++--- cmd/psweb/main.go | 2 +- cmd/psweb/templates/liquid.gohtml | 2 +- 6 files changed, 16 insertions(+), 7 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index ab05dd0..06ff138 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -13,7 +13,7 @@ "program": "${workspaceFolder}/cmd/psweb/", "showLog": false, "envFile": "${workspaceFolder}/.env", - "args": ["-datadir", "/home/vlad/.peerswap2"] + //"args": ["-datadir", "/home/vlad/.peerswap2"] } ] } diff --git a/CHANGELOG.md b/CHANGELOG.md index 13f25f0..d3b5b4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,12 @@ # Versions +## 1.6.5 + +- Pre-fill 0 if possible swap amount is below 100,000 + ## 1.6.4 -- Implement advertizing L-BTC balance: LND send and receive, CLN send +- Implement advertising L-BTC balance: LND send and receive, CLN send - Pre-fill swap amount to return the channel closer to 50/50 if viable - Persist NodeId per ChannelId map to avoid *closed channel* - Apply AutoFees even while HTLC is pending diff --git a/cmd/psweb/handlers.go b/cmd/psweb/handlers.go index 0bdb522..1dba611 100644 --- a/cmd/psweb/handlers.go +++ b/cmd/psweb/handlers.go @@ -416,6 +416,9 @@ func peerHandler(w http.ResponseWriter, r *http.Request) { // arbitrary haircut to avoid 'no matching outgoing channel available' maxLiquidSwapIn := min(satAmount-2000, maxRemoteBalance-10000) + if maxLiquidSwapIn < 100_000 { + maxLiquidSwapIn = 0 + } peerLiquidBalance := int64(-1) maxLiquidSwapOut := uint64(0) @@ -428,6 +431,8 @@ func peerHandler(w http.ResponseWriter, r *http.Request) { maxLiquidSwapOut = uint64(max(0, min(int64(maxLocalBalance)-5000, peerLiquidBalance-20300))) if maxLiquidSwapOut >= 100_000 { selectedChannel = peer.Channels[maxLocalBalanceIndex].ChannelId + } else { + maxLiquidSwapOut = 0 } } diff --git a/cmd/psweb/ln/lnd.go b/cmd/psweb/ln/lnd.go index 10977c1..6d2df2c 100644 --- a/cmd/psweb/ln/lnd.go +++ b/cmd/psweb/ln/lnd.go @@ -1514,7 +1514,7 @@ func ListPeers(client lnrpc.LightningClient, peerId string, excludeIds *[]string if channel.RemotePubkey == lndPeer.PubKey { peer.Channels = append(peer.Channels, &peerswaprpc.PeerSwapPeerChannel{ ChannelId: channel.ChanId, - LocalBalance: uint64(channel.LocalBalance + channel.UnsettledBalance), + LocalBalance: uint64(channel.LocalBalance), RemoteBalance: uint64(channel.RemoteBalance), Active: channel.Active, }) @@ -1816,7 +1816,7 @@ func applyAutoFee(client lnrpc.LightningClient, channelId uint64, htlcFail bool) localBalance := int64(0) for _, ch := range res.Channels { if ch.ChanId == channelId { - localBalance = ch.LocalBalance + ch.UnsettledBalance + localBalance = ch.LocalBalance break } } @@ -1910,7 +1910,7 @@ func ApplyAutoFees() { oldFee := int(policy.FeeRateMilliMsat) newFee := oldFee - liqPct := int((ch.LocalBalance + ch.UnsettledBalance) * 100 / r.Capacity) + liqPct := int(ch.LocalBalance * 100 / r.Capacity) newFee = calculateAutoFee(ch.ChanId, params, liqPct, oldFee) diff --git a/cmd/psweb/main.go b/cmd/psweb/main.go index 992ff06..7223750 100644 --- a/cmd/psweb/main.go +++ b/cmd/psweb/main.go @@ -35,7 +35,7 @@ import ( const ( // App version tag - version = "v1.6.4" + version = "v1.6.5" ) type SwapParams struct { diff --git a/cmd/psweb/templates/liquid.gohtml b/cmd/psweb/templates/liquid.gohtml index 9f78d56..a328f35 100644 --- a/cmd/psweb/templates/liquid.gohtml +++ b/cmd/psweb/templates/liquid.gohtml @@ -99,7 +99,7 @@
-

Advertize L-BTC Balance

+

Advertise L-BTC Balance

From a8b8aed35c42502107699ca42a1ec305b907cec0 Mon Sep 17 00:00:00 2001 From: Impa10r Date: Thu, 11 Jul 2024 15:35:47 +0200 Subject: [PATCH 2/6] Reduce frequency of balance announcements --- cmd/psweb/ln/common.go | 3 +++ cmd/psweb/main.go | 20 ++++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/cmd/psweb/ln/common.go b/cmd/psweb/ln/common.go index 589f283..f5af41d 100644 --- a/cmd/psweb/ln/common.go +++ b/cmd/psweb/ln/common.go @@ -198,6 +198,9 @@ var ( // received via custom messages, per peer nodeId LiquidBalances = make(map[string]*BalanceInfo) + + // sent via custom messages + SentLiquidBalances = make(map[string]*BalanceInfo) ) func toSats(amount float64) int64 { diff --git a/cmd/psweb/main.go b/cmd/psweb/main.go index 7223750..ebab75e 100644 --- a/cmd/psweb/main.go +++ b/cmd/psweb/main.go @@ -1669,12 +1669,28 @@ func advertizeBalance() { defer clean() for _, peer := range res3.GetPeers() { - ln.SendCustomMessage(cl, peer.NodeId, &ln.Message{ + + ptr := ln.SentLiquidBalances[peer.NodeId] + if ptr != nil { + if ptr.Amount == satAmount && ptr.TimeStamp > time.Now().AddDate(0, 0, -1).Unix() { + // do not repeat within 24 hours + continue + } + } + + if ln.SendCustomMessage(cl, peer.NodeId, &ln.Message{ Version: ln.MessageVersion, Memo: "balance", Asset: "lbtc", Amount: satAmount, - }) + }) == nil { + // save announcement + if ptr == nil { + ln.SentLiquidBalances[peer.NodeId] = new(ln.BalanceInfo) + } + ln.SentLiquidBalances[peer.NodeId].Amount = satAmount + ln.SentLiquidBalances[peer.NodeId].TimeStamp = time.Now().Unix() + } // delete stale received balances over 24 hours ago if ptr := ln.LiquidBalances[peer.NodeId]; ptr != nil { From 04ca065090745871098715ce267db91d9afa2ba7 Mon Sep 17 00:00:00 2001 From: Impa10r Date: Thu, 11 Jul 2024 15:36:40 +0200 Subject: [PATCH 3/6] Reduce frequency of balance announcements --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d3b5b4c..d504303 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## 1.6.5 +- Reduce frequency of balance announcements to 24hr unless changed - Pre-fill 0 if possible swap amount is below 100,000 ## 1.6.4 From 4cb0354da2f4465d7ad9cae3322eecf5b2505643 Mon Sep 17 00:00:00 2001 From: Impa10r Date: Thu, 11 Jul 2024 15:55:26 +0200 Subject: [PATCH 4/6] Poll balances --- .vscode/launch.json | 2 +- cmd/psweb/ln/common.go | 3 +++ cmd/psweb/ln/lnd.go | 17 +++++++++++++++++ cmd/psweb/main.go | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 06ff138..ab05dd0 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -13,7 +13,7 @@ "program": "${workspaceFolder}/cmd/psweb/", "showLog": false, "envFile": "${workspaceFolder}/.env", - //"args": ["-datadir", "/home/vlad/.peerswap2"] + "args": ["-datadir", "/home/vlad/.peerswap2"] } ] } diff --git a/cmd/psweb/ln/common.go b/cmd/psweb/ln/common.go index f5af41d..00203ae 100644 --- a/cmd/psweb/ln/common.go +++ b/cmd/psweb/ln/common.go @@ -201,6 +201,9 @@ var ( // sent via custom messages SentLiquidBalances = make(map[string]*BalanceInfo) + + // current LiquidBalance + LiquidBalance uint64 ) func toSats(amount float64) int64 { diff --git a/cmd/psweb/ln/lnd.go b/cmd/psweb/ln/lnd.go index 6d2df2c..17651a5 100644 --- a/cmd/psweb/ln/lnd.go +++ b/cmd/psweb/ln/lnd.go @@ -1188,6 +1188,23 @@ func subscribeMessages(ctx context.Context, client lnrpc.LightningClient) error nodeId := hex.EncodeToString(data.Peer) + if msg.Memo == "poll" && msg.Asset == "lbtc" { + if SendCustomMessage(client, nodeId, &Message{ + Version: MessageVersion, + Memo: "balance", + Asset: "lbtc", + Amount: LiquidBalance, + }) == nil { + // save announcement + ptr := SentLiquidBalances[nodeId] + if ptr == nil { + SentLiquidBalances[nodeId] = new(BalanceInfo) + } + SentLiquidBalances[nodeId].Amount = LiquidBalance + SentLiquidBalances[nodeId].TimeStamp = time.Now().Unix() + } + } + if msg.Memo == "balance" && msg.Asset == "lbtc" { ts := time.Now().Unix() if LiquidBalances[nodeId] == nil { diff --git a/cmd/psweb/main.go b/cmd/psweb/main.go index ebab75e..eaff356 100644 --- a/cmd/psweb/main.go +++ b/cmd/psweb/main.go @@ -220,6 +220,11 @@ func main() { // CLN: refresh forwarding stats go ln.CacheForwards() + // request balance refresh from peers + if ln.Implementation == "LND" { + go pollBalances() + } + // Handle termination signals signalChan := make(chan os.Signal, 1) signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM) @@ -1657,6 +1662,9 @@ func advertizeBalance() { satAmount := res2.GetSatAmount() + // save to poll replies + ln.LiquidBalance = satAmount + res3, err := ps.ListPeers(client) if err != nil { return @@ -1700,3 +1708,33 @@ func advertizeBalance() { } } } + +func pollBalances() { + + client, cleanup, err := ps.GetClient(config.Config.RpcHost) + if err != nil { + return + } + defer cleanup() + + res, err := ps.ListPeers(client) + if err != nil { + return + } + + cl, clean, er := ln.GetClient() + if er != nil { + return + } + defer clean() + + for _, peer := range res.GetPeers() { + if ln.SendCustomMessage(cl, peer.NodeId, &ln.Message{ + Version: ln.MessageVersion, + Memo: "poll", + Asset: "lbtc", + }) != nil { + log.Println("Failed to poll L-BTC balance from", getNodeAlias(peer.NodeId)) + } + } +} From 3d34929bf8aee4f6b14ba8b69d06b3db2e488b6b Mon Sep 17 00:00:00 2001 From: Impa10r Date: Thu, 11 Jul 2024 16:03:34 +0200 Subject: [PATCH 5/6] Reply to poll if advertizing --- cmd/psweb/handlers.go | 10 +++++----- cmd/psweb/ln/common.go | 6 ++++++ cmd/psweb/ln/lnd.go | 2 +- cmd/psweb/main.go | 5 +---- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/cmd/psweb/handlers.go b/cmd/psweb/handlers.go index 1dba611..7f65861 100644 --- a/cmd/psweb/handlers.go +++ b/cmd/psweb/handlers.go @@ -199,7 +199,7 @@ func indexHandler(w http.ResponseWriter, r *http.Request) { Filter: nodeId != "" || state != "" || role != "", AutoSwapEnabled: config.Config.AutoSwapEnabled, PeginPending: config.Config.PeginTxId != "" && config.Config.PeginClaimScript != "", - AdvertizeEnabled: advertizeLiquidBalance, + AdvertizeEnabled: ln.AdvertizeLiquidBalance, } // executing template named "homepage" with retries @@ -1552,7 +1552,7 @@ func liquidHandler(w http.ResponseWriter, r *http.Request) { AutoSwapThresholdPPM: config.Config.AutoSwapThresholdPPM, AutoSwapTargetPct: config.Config.AutoSwapTargetPct, AutoSwapCandidate: &candidate, - AdvertizeEnabled: advertizeLiquidBalance, + AdvertizeEnabled: ln.AdvertizeLiquidBalance, } // executing template named "liquid" @@ -1578,12 +1578,12 @@ func submitHandler(w http.ResponseWriter, r *http.Request) { switch action { case "advertizeLiquidBalance": - advertizeLiquidBalance = r.FormValue("enabled") == "on" - db.Save("Peers", "AdvertizeLiquidBalance", advertizeLiquidBalance) + ln.AdvertizeLiquidBalance = r.FormValue("enabled") == "on" + db.Save("Peers", "AdvertizeLiquidBalance", ln.AdvertizeLiquidBalance) msg := "Broadcasting Liquid Balance is " - if advertizeLiquidBalance { + if ln.AdvertizeLiquidBalance { msg += "Enabled" } else { msg += "Disabled" diff --git a/cmd/psweb/ln/common.go b/cmd/psweb/ln/common.go index 00203ae..b85145d 100644 --- a/cmd/psweb/ln/common.go +++ b/cmd/psweb/ln/common.go @@ -204,6 +204,9 @@ var ( // current LiquidBalance LiquidBalance uint64 + + // global setting + AdvertizeLiquidBalance = false ) func toSats(amount float64) int64 { @@ -291,6 +294,9 @@ func LoadDB() { db.Load("AutoFees", "AutoFee", &AutoFee) db.Load("AutoFees", "AutoFeeDefaults", &AutoFeeDefaults) + // on or off + db.Load("Peers", "AdvertizeLiquidBalance", &AdvertizeLiquidBalance) + // drop non-array legacy log var log map[uint64]interface{} db.Load("AutoFees", "AutoFeeLog", &log) diff --git a/cmd/psweb/ln/lnd.go b/cmd/psweb/ln/lnd.go index 17651a5..bd5bab2 100644 --- a/cmd/psweb/ln/lnd.go +++ b/cmd/psweb/ln/lnd.go @@ -1188,7 +1188,7 @@ func subscribeMessages(ctx context.Context, client lnrpc.LightningClient) error nodeId := hex.EncodeToString(data.Peer) - if msg.Memo == "poll" && msg.Asset == "lbtc" { + if msg.Memo == "poll" && msg.Asset == "lbtc" && AdvertizeLiquidBalance { if SendCustomMessage(client, nodeId, &Message{ Version: MessageVersion, Memo: "balance", diff --git a/cmd/psweb/main.go b/cmd/psweb/main.go index eaff356..c7d001e 100644 --- a/cmd/psweb/main.go +++ b/cmd/psweb/main.go @@ -66,8 +66,6 @@ var ( autoSwapId string // store peer pub mapped to channel Id peerNodeId = make(map[uint64]string) - // global setting - advertizeLiquidBalance = false ) func main() { @@ -122,7 +120,6 @@ func main() { // Load persisted data from database ln.LoadDB() db.Load("Peers", "NodeId", &peerNodeId) - db.Load("Peers", "AdvertizeLiquidBalance", &advertizeLiquidBalance) db.Load("Swaps", "txFee", &txFee) // fetch all chain costs @@ -1635,7 +1632,7 @@ func last(x int, a interface{}) bool { func advertizeBalance() { - if !advertizeLiquidBalance { + if !ln.AdvertizeLiquidBalance { return } From 71fcba1700aa729a7bd95303039f30327cf9b45d Mon Sep 17 00:00:00 2001 From: Impa10r Date: Thu, 11 Jul 2024 21:24:48 +0200 Subject: [PATCH 6/6] Refresh belences after 24h --- cmd/psweb/ln/lnd.go | 2 ++ cmd/psweb/main.go | 26 +++++++++++++++----------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/cmd/psweb/ln/lnd.go b/cmd/psweb/ln/lnd.go index bd5bab2..720dfbf 100644 --- a/cmd/psweb/ln/lnd.go +++ b/cmd/psweb/ln/lnd.go @@ -1188,6 +1188,7 @@ func subscribeMessages(ctx context.Context, client lnrpc.LightningClient) error nodeId := hex.EncodeToString(data.Peer) + // received request for information if msg.Memo == "poll" && msg.Asset == "lbtc" && AdvertizeLiquidBalance { if SendCustomMessage(client, nodeId, &Message{ Version: MessageVersion, @@ -1205,6 +1206,7 @@ func subscribeMessages(ctx context.Context, client lnrpc.LightningClient) error } } + // received information if msg.Memo == "balance" && msg.Asset == "lbtc" { ts := time.Now().Unix() if LiquidBalances[nodeId] == nil { diff --git a/cmd/psweb/main.go b/cmd/psweb/main.go index c7d001e..6899611 100644 --- a/cmd/psweb/main.go +++ b/cmd/psweb/main.go @@ -1659,7 +1659,7 @@ func advertizeBalance() { satAmount := res2.GetSatAmount() - // save to poll replies + // store for replies to poll requests ln.LiquidBalance = satAmount res3, err := ps.ListPeers(client) @@ -1674,11 +1674,23 @@ func advertizeBalance() { defer clean() for _, peer := range res3.GetPeers() { + // refresh balances received over 24 hours ago + if ptr := ln.LiquidBalances[peer.NodeId]; ptr != nil { + if ptr.TimeStamp < time.Now().AddDate(0, 0, -1).Unix() { + ln.SendCustomMessage(cl, peer.NodeId, &ln.Message{ + Version: ln.MessageVersion, + Memo: "poll", + Asset: "lbtc", + }) + // delete stale information + ln.LiquidBalances[peer.NodeId] = nil + } + } ptr := ln.SentLiquidBalances[peer.NodeId] if ptr != nil { if ptr.Amount == satAmount && ptr.TimeStamp > time.Now().AddDate(0, 0, -1).Unix() { - // do not repeat within 24 hours + // do not repeat within 24 hours unless changed continue } } @@ -1689,25 +1701,17 @@ func advertizeBalance() { Asset: "lbtc", Amount: satAmount, }) == nil { - // save announcement + // save announcement details if ptr == nil { ln.SentLiquidBalances[peer.NodeId] = new(ln.BalanceInfo) } ln.SentLiquidBalances[peer.NodeId].Amount = satAmount ln.SentLiquidBalances[peer.NodeId].TimeStamp = time.Now().Unix() } - - // delete stale received balances over 24 hours ago - if ptr := ln.LiquidBalances[peer.NodeId]; ptr != nil { - if ptr.TimeStamp < time.Now().AddDate(0, 0, -1).Unix() { - ln.LiquidBalances[peer.NodeId] = nil - } - } } } func pollBalances() { - client, cleanup, err := ps.GetClient(config.Config.RpcHost) if err != nil { return