Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
a6b4bf7
sqlc: static address migrations, models, queries
hieblmi Nov 9, 2023
d174c29
looprpc: static address creation
hieblmi Feb 14, 2024
a688cbb
log: static address sub logger
hieblmi Nov 9, 2023
595dd7f
loopdb: static address store
hieblmi Nov 9, 2023
437f38a
staticaddr: static address manager
hieblmi Nov 9, 2023
4f64f33
staticaddr: static address server
hieblmi Feb 14, 2024
5e43dd9
daemon: integrate static address manager and sql store
hieblmi Nov 9, 2023
5b71364
perms: static address creation permission
hieblmi Nov 9, 2023
f5bbaec
loop: static address creation client command
hieblmi Nov 9, 2023
7207af0
looprpc: list unspent static address
hieblmi Nov 9, 2023
78fca2b
staticaddr: track and list spends in manager
hieblmi Oct 25, 2023
c85792f
staticaddr: list unspent outputs in server
hieblmi Oct 25, 2023
fa4abf8
perms: list unspent outputs
hieblmi Oct 25, 2023
e477d13
loop: list unspent static address outputs
hieblmi Oct 25, 2023
208f8e7
looprpc: include static address in swap client
hieblmi Feb 26, 2024
fc921a2
sqlc: deposit queries, models and migrations
hieblmi Mar 7, 2024
d09902e
staticaddr: interfaces
hieblmi Mar 7, 2024
aa5fb7a
staticaddr: deposit logger
hieblmi Mar 7, 2024
6882823
staticaddr: deposit manager and fsm
hieblmi Mar 7, 2024
f898c14
staticaddr: deposits for server and daemon
hieblmi Mar 7, 2024
3e898f8
staticaddr: add swap client to cmd
hieblmi Mar 7, 2024
73c033c
unit: manager tests
hieblmi Apr 23, 2024
36a75da
staticaddr: public deposit method scope
hieblmi Apr 25, 2024
90ab546
sqlc: withdrawal address for deposits
hieblmi May 6, 2024
89d94a4
looprpc: deposit withdrawal endpoint
hieblmi May 6, 2024
413d209
swapserverrpc: server withdrawal endpoint
hieblmi May 6, 2024
a5f6b14
log: unified static address logger
hieblmi May 6, 2024
9b9f6e4
staticaddr: address and deposit adjustments for withdrawals
hieblmi May 6, 2024
5ed8e89
staticaddr: withdrawal manager and interface
hieblmi May 6, 2024
e957d14
loopd: static address withdrawals support
hieblmi May 6, 2024
99d7423
loop: static address withdrawals support
hieblmi May 6, 2024
120b7af
looprpc: static address summary
hieblmi Jun 5, 2024
35da39c
staticaddr: expose static address to client summary
hieblmi Jun 5, 2024
3174b8a
loopd: static address summary
hieblmi Jun 5, 2024
ec8f54b
looprpc: deposit outpoints for QuoteRequest
hieblmi Jun 6, 2024
b9723ce
swapserverrpc: number of deposits for ServerLoopInQuoteRequest
hieblmi Jun 6, 2024
df74f06
loopd: quoting for static address loop-ins
hieblmi Jun 6, 2024
79142ff
cmd: quote for static address loop-ins
hieblmi Jun 6, 2024
cf39fba
looprpc: static address loop-ins
hieblmi Jul 30, 2024
bd7a043
sqlc: loop-in tables and queries
hieblmi Jul 30, 2024
ec254ae
log: static address loop-in logging
hieblmi Jul 30, 2024
de95fd0
staticaddr: enable deposits for swaps
hieblmi Jul 30, 2024
59cc8ce
loopin: public scope for ValidateLoopInContract
hieblmi Sep 26, 2024
6526ef2
interface: add StaticAddressLoopInRequest interface
hieblmi Sep 26, 2024
7f882c4
staticaddr: configurable max htlc tx fee
hieblmi Oct 17, 2024
dc2024a
staticaddr: loopin
hieblmi Oct 30, 2024
1f2f054
staticaddr: sql_store
hieblmi Oct 30, 2024
0b9bd0a
staticaddr: swap manager and fsm
hieblmi Oct 24, 2024
7c16b6b
unit: manager mocks for static address loop-in
hieblmi Jul 30, 2024
a082f01
loopd: static address loop-in support
hieblmi Jul 30, 2024
e8a8daf
cmd: static address loop-in
hieblmi Jul 30, 2024
ec3070f
staticaddr: cmd listdeposits and listswaps
hieblmi Nov 5, 2024
d9a3920
staticaddr: separate file for rpc service
hieblmi Nov 5, 2024
2962d2b
staticaddr: change min deposit confs from 3 to 6
hieblmi Nov 5, 2024
ed242f7
staticaddr: fix fsm logging
hieblmi Nov 5, 2024
44092a7
Merge pull request #846 from hieblmi/static-fixes
hieblmi Nov 5, 2024
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
34 changes: 28 additions & 6 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,13 @@ var (
ErrSwapAmountTooHigh = errors.New("swap amount too high")

// ErrExpiryTooFar is returned when the server proposes an expiry that
// is too soon for us.
// is too far in the future.
ErrExpiryTooFar = errors.New("swap expiry too far")

// ErrExpiryTooSoon is returned when the server proposes an expiry that
// is too soon.
ErrExpiryTooSoon = errors.New("swap expiry too soon")

// ErrInsufficientBalance indicates insufficient confirmed balance to
// publish a swap.
ErrInsufficientBalance = errors.New("insufficient confirmed balance")
Expand Down Expand Up @@ -131,6 +135,22 @@ type ClientConfig struct {
// MaxPaymentRetries is the maximum times we retry an off-chain payment
// (used in loop out).
MaxPaymentRetries int

// MaxStaticAddrHtlcFeePercentage is the percentage of the swap amount
// that we allow the server to charge for the htlc transaction.
// Although highly unlikely, this is a defense against the server
// publishing the htlc without paying the swap invoice, forcing us to
// sweep the timeout path.
MaxStaticAddrHtlcFeePercentage float64

// MaxStaticAddrHtlcBackupFeePercentage is the percentage of the swap
// amount that we allow the server to charge for the htlc backup
// transactions. This is a defense against the server publishing the
// htlc backup without paying the swap invoice, forcing us to sweep the
// timeout path. This value is elevated compared to
// MaxStaticAddrHtlcFeePercentage since it serves the server as backup
// transaction in case of fee spikes.
MaxStaticAddrHtlcBackupFeePercentage float64
}

// NewClient returns a new instance to initiate swaps with.
Expand Down Expand Up @@ -646,9 +666,9 @@ func (s *Client) LoopIn(globalCtx context.Context,
return swapInfo, nil
}

// LoopInQuote takes an amount and returns a break down of estimated
// costs for the client. Both the swap server and the on-chain fee estimator are
// queried to get to build the quote response.
// LoopInQuote takes an amount and returns a breakdown of estimated costs for
// the client. Both the swap server and the on-chain fee estimator are queried
// to get to build the quote response.
func (s *Client) LoopInQuote(ctx context.Context,
request *LoopInQuoteRequest) (*LoopInQuote, error) {

Expand Down Expand Up @@ -694,7 +714,7 @@ func (s *Client) LoopInQuote(ctx context.Context,

quote, err := s.Server.GetLoopInQuote(
ctx, request.Amount, s.lndServices.NodePubkey, request.LastHop,
request.RouteHints, request.Initiator,
request.RouteHints, request.Initiator, request.NumDeposits,
)
if err != nil {
return nil, err
Expand All @@ -704,7 +724,9 @@ func (s *Client) LoopInQuote(ctx context.Context,

// We don't calculate the on-chain fee if the HTLC is going to be
// published externally.
if request.ExternalHtlc {
// We also don't calculate the on-chain fee if the loop in is funded by
// static address deposits because we don't publish the HTLC on-chain.
if request.ExternalHtlc || request.NumDeposits > 0 {
return &LoopInQuote{
SwapFee: swapFee,
MinerFee: 0,
Expand Down
7 changes: 7 additions & 0 deletions cmd/loop/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ func main() {
setLiquidityRuleCommand, suggestSwapCommand, setParamsCommand,
getInfoCommand, abandonSwapCommand, reservationsCommands,
instantOutCommand, listInstantOutsCommand,
staticAddressCommands,
}

err := app.Run(os.Args)
Expand Down Expand Up @@ -279,6 +280,12 @@ func displayInDetails(req *looprpc.QuoteRequest,
"wallet.\n\n")
}

if req.DepositOutpoints != nil {
fmt.Printf("On-chain fees for static address loop-ins are not " +
"included.\nThey were already paid when the deposits " +
"were created.\n\n")
}

printQuoteInResp(req, resp, verbose)

fmt.Printf("\nCONTINUE SWAP? (y/n): ")
Expand Down
82 changes: 70 additions & 12 deletions cmd/loop/quote.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"time"

"github.com/btcsuite/btcd/btcutil"
"github.com/lightninglabs/loop"
"github.com/lightninglabs/loop/looprpc"
"github.com/lightningnetwork/lnd/routing/route"
Expand All @@ -19,10 +20,11 @@ var quoteCommand = cli.Command{
}

var quoteInCommand = cli.Command{
Name: "in",
Usage: "get a quote for the cost of a loop in swap",
ArgsUsage: "amt",
Description: "Allows to determine the cost of a swap up front",
Name: "in",
Usage: "get a quote for the cost of a loop in swap",
ArgsUsage: "amt",
Description: "Allows to determine the cost of a swap up front." +
"Either specify an amount or deposit outpoints.",
Flags: []cli.Flag{
cli.StringFlag{
Name: lastHopFlag.Name,
Expand All @@ -33,20 +35,38 @@ var quoteInCommand = cli.Command{
verboseFlag,
privateFlag,
routeHintsFlag,
cli.StringSliceFlag{
Name: "deposit_outpoint",
Usage: "one or more static address deposit outpoints " +
"to quote for. Deposit outpoints are not to " +
"be used in combination with an amount. Each" +
"additional outpoint can be added by " +
"specifying --deposit_outpoint tx_id:idx",
},
},
Action: quoteIn,
}

func quoteIn(ctx *cli.Context) error {
// Show command help if the incorrect number arguments was provided.
if ctx.NArg() != 1 {
if ctx.NArg() != 1 && !ctx.IsSet("deposit_outpoint") {
return cli.ShowCommandHelp(ctx, "in")
}

args := ctx.Args()
amt, err := parseAmt(args[0])
if err != nil {
return err
var (
manualAmt btcutil.Amount
depositAmt btcutil.Amount
depositOutpoints []string
err error
ctxb = context.Background()
)

if ctx.NArg() == 1 {
args := ctx.Args()
manualAmt, err = parseAmt(args[0])
if err != nil {
return err
}
}

client, cleanup, err := getClient(ctx)
Expand All @@ -62,11 +82,20 @@ func quoteIn(ctx *cli.Context) error {
return err
}

if ctx.IsSet("deposit_outpoint") {
depositOutpoints = ctx.StringSlice("deposit_outpoint")
depositAmt, err = depositAmount(ctxb, client, depositOutpoints)
if err != nil {
return err
}
}

quoteReq := &looprpc.QuoteRequest{
Amt: int64(amt),
Amt: int64(manualAmt),
ConfTarget: int32(ctx.Uint64("conf_target")),
LoopInRouteHints: hints,
Private: ctx.Bool(privateFlag.Name),
DepositOutpoints: depositOutpoints,
}

if ctx.IsSet(lastHopFlag.Name) {
Expand All @@ -80,7 +109,6 @@ func quoteIn(ctx *cli.Context) error {
quoteReq.LoopInLastHop = lastHopVertex[:]
}

ctxb := context.Background()
quoteResp, err := client.GetLoopInQuote(ctxb, quoteReq)
if err != nil {
return err
Expand All @@ -98,10 +126,36 @@ func quoteIn(ctx *cli.Context) error {
"amount.\n")
}

// If the user specified static address deposits, we quoted for their
// total value and need to display that value instead of the manually
// selected one.
if manualAmt == 0 {
quoteReq.Amt = int64(depositAmt)
}
printQuoteInResp(quoteReq, quoteResp, ctx.Bool("verbose"))
return nil
}

func depositAmount(ctx context.Context, client looprpc.SwapClientClient,
depositOutpoints []string) (btcutil.Amount, error) {

addressSummary, err := client.ListStaticAddressDeposits(
ctx, &looprpc.ListStaticAddressDepositsRequest{
Outpoints: depositOutpoints,
},
)
if err != nil {
return 0, err
}

var depositAmt btcutil.Amount
for _, deposit := range addressSummary.FilteredDeposits {
depositAmt += btcutil.Amount(deposit.Value)
}

return depositAmt, nil
}

var quoteOutCommand = cli.Command{
Name: "out",
Usage: "get a quote for the cost of a loop out swap",
Expand Down Expand Up @@ -174,7 +228,11 @@ func printQuoteInResp(req *looprpc.QuoteRequest,

totalFee := resp.HtlcPublishFeeSat + resp.SwapFeeSat

fmt.Printf(satAmtFmt, "Send on-chain:", req.Amt)
if req.DepositOutpoints != nil {
fmt.Printf(satAmtFmt, "Previously deposited on-chain:", req.Amt)
} else {
fmt.Printf(satAmtFmt, "Send on-chain:", req.Amt)
}
fmt.Printf(satAmtFmt, "Receive off-chain:", req.Amt-totalFee)

switch {
Expand Down
Loading
Loading