Skip to content

Commit

Permalink
Merge pull request #642 from hieblmi/static-addr-1
Browse files Browse the repository at this point in the history
[1/?] Static Loop-In Address - Create
  • Loading branch information
hieblmi authored Mar 4, 2024
2 parents a66210b + 11d058d commit d5cb601
Show file tree
Hide file tree
Showing 28 changed files with 1,834 additions and 433 deletions.
2 changes: 1 addition & 1 deletion client.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ func NewClient(dbDir string, loopDB loopdb.SwapStore,
config := &clientConfig{
LndServices: cfg.Lnd,
Server: swapServerClient,
Store: loopDB,
Conn: swapServerClient.conn,
Store: loopDB,
LsatStore: lsatStore,
CreateExpiryTimer: func(d time.Duration) <-chan time.Time {
return time.NewTimer(d).C
Expand Down
3 changes: 3 additions & 0 deletions cmd/loop/loopin.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ var (
Name: "in",
Usage: "perform an on-chain to off-chain swap (loop in)",
ArgsUsage: "amt",
Subcommands: []cli.Command{
staticAddressCommands,
},
Description: `
Send the amount in satoshis specified by the amt argument
off-chain.
Expand Down
2 changes: 1 addition & 1 deletion cmd/loop/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func main() {
listSwapsCommand, swapInfoCommand, getLiquidityParamsCommand,
setLiquidityRuleCommand, suggestSwapCommand, setParamsCommand,
getInfoCommand, abandonSwapCommand, reservationsCommands,
instantOutCommand,
instantOutCommand, staticAddressCommands,
}

err := app.Run(os.Args)
Expand Down
76 changes: 76 additions & 0 deletions cmd/loop/staticaddr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package main

import (
"context"
"fmt"

"github.com/lightninglabs/loop/looprpc"
"github.com/urfave/cli"
)

var staticAddressCommands = cli.Command{
Name: "static",
ShortName: "s",
Usage: "manage static loop-in addresses",
Category: "StaticAddress",
Subcommands: []cli.Command{
newStaticAddressCommand,
},
}

var newStaticAddressCommand = cli.Command{
Name: "new",
ShortName: "n",
Usage: "Create a new static loop in address.",
Description: `
Requests a new static loop in address from the server. Funds that are
sent to this address will be locked by a 2:2 multisig between us and the
loop server, or a timeout path that we can sweep once it opens up. The
funds can either be cooperatively spent with a signature from the server
or looped in.
`,
Action: newStaticAddress,
}

func newStaticAddress(ctx *cli.Context) error {
ctxb := context.Background()
if ctx.NArg() > 0 {
return cli.ShowCommandHelp(ctx, "new")
}

client, cleanup, err := getAddressClient(ctx)
if err != nil {
return err
}
defer cleanup()

resp, err := client.NewAddress(
ctxb, &looprpc.NewAddressRequest{},
)
if err != nil {
return err
}

fmt.Printf("Received a new static loop-in address from the server: "+
"%s\n", resp.Address)

return nil
}

func getAddressClient(ctx *cli.Context) (looprpc.StaticAddressClientClient,
func(), error) {

rpcServer := ctx.GlobalString("rpcserver")
tlsCertPath, macaroonPath, err := extractPathArgs(ctx)
if err != nil {
return nil, nil, err
}
conn, err := getClientConn(rpcServer, tlsCertPath, macaroonPath)
if err != nil {
return nil, nil, err
}
cleanup := func() { conn.Close() }

addressClient := looprpc.NewStaticAddressClientClient(conn)
return addressClient, cleanup, nil
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ require (
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3
github.com/jackc/pgconn v1.14.0
github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa
github.com/jackc/pgx/v4 v4.18.1
github.com/jessevdk/go-flags v1.4.0
github.com/lib/pq v1.10.7
github.com/lightninglabs/aperture v0.1.21-beta.0.20230705004936-87bb996a4030
Expand Down Expand Up @@ -96,7 +97,6 @@ require (
github.com/jackc/pgproto3/v2 v2.3.2 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/pgtype v1.14.0 // indirect
github.com/jackc/pgx/v4 v4.18.1 // indirect
github.com/jackpal/gateway v1.0.5 // indirect
github.com/jackpal/go-nat-pmp v0.0.0-20170405195558-28a68d0c24ad // indirect
github.com/jonboulle/clockwork v0.2.2 // indirect
Expand Down
79 changes: 42 additions & 37 deletions loopd/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,13 @@ import (
"github.com/lightninglabs/lndclient"
"github.com/lightninglabs/loop"
"github.com/lightninglabs/loop/instantout"
"github.com/lightninglabs/loop/instantout/reservation"
"github.com/lightninglabs/loop/loopd/perms"
"github.com/lightninglabs/loop/loopdb"
"github.com/lightninglabs/loop/sweepbatcher"

"github.com/lightninglabs/loop/instantout/reservation"
loop_looprpc "github.com/lightninglabs/loop/looprpc"

"github.com/lightninglabs/loop/staticaddr"
loop_swaprpc "github.com/lightninglabs/loop/swapserverrpc"
"github.com/lightninglabs/loop/sweepbatcher"
"github.com/lightningnetwork/lnd/clock"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/macaroons"
Expand Down Expand Up @@ -69,6 +68,12 @@ type Daemon struct {
// same process.
swapClientServer

// AddressServer is the embedded RPC server that satisfies the
// static address client RPC interface. We embed this struct so the
// Daemon itself can be registered to an existing grpc.Server to run as
// a subserver in the same process.
*staticaddr.AddressServer

// ErrChan is an error channel that users of the Daemon struct must use
// to detect runtime errors and also whether a shutdown is fully
// completed.
Expand Down Expand Up @@ -234,6 +239,7 @@ func (d *Daemon) startWebServers() error {
grpc.StreamInterceptor(streamInterceptor),
)
loop_looprpc.RegisterSwapClientServer(d.grpcServer, d)
loop_looprpc.RegisterStaticAddressClientServer(d.grpcServer, d)

// Register our debug server if it is compiled in.
d.registerDebugServer()
Expand Down Expand Up @@ -545,6 +551,26 @@ func (d *Daemon) initialize(withMacaroonService bool) error {
instantOutManager: instantOutManager,
}

// Create a static address server client.
staticAddressClient := loop_swaprpc.NewStaticAddressServerClient(
swapClient.Conn,
)

store := staticaddr.NewSqlStore(baseDb)

cfg := &staticaddr.ManagerConfig{
AddressClient: staticAddressClient,
SwapClient: swapClient,
Store: store,
WalletKit: d.lnd.WalletKit,
ChainParams: d.lnd.ChainParams,
}
staticAddressManager := staticaddr.NewAddressManager(cfg)

d.AddressServer = staticaddr.NewAddressServer(
staticAddressClient, staticAddressManager,
)

// Retrieve all currently existing swaps from the database.
swapsList, err := d.impl.FetchSwaps(d.mainCtx)
if err != nil {
Expand Down Expand Up @@ -635,42 +661,21 @@ func (d *Daemon) initialize(withMacaroonService bool) error {
}()
}

// Start the instant out manager.
if d.instantOutManager != nil {
d.wg.Add(1)
initChan := make(chan struct{})
go func() {
defer d.wg.Done()

getInfo, err := d.lnd.Client.GetInfo(d.mainCtx)
if err != nil {
d.internalErrChan <- err
return
}
// Start the static address manager.
d.wg.Add(1)
go func() {
defer d.wg.Done()

log.Info("Starting instantout manager")
defer log.Info("Instantout manager stopped")
log.Info("Starting static address manager...")
err = staticAddressManager.Run(d.mainCtx)
if err != nil && !errors.Is(context.Canceled, err) {
d.internalErrChan <- err
}

err = d.instantOutManager.Run(
d.mainCtx, initChan, int32(getInfo.BlockHeight),
)
if err != nil && !errors.Is(err, context.Canceled) {
d.internalErrChan <- err
}
}()
log.Info("Static address manager stopped")
}()

// Wait for the instantout server to be ready before starting the
// grpc server.
timeOutCtx, cancel := context.WithTimeout(d.mainCtx, 10*time.Second)
select {
case <-timeOutCtx.Done():
cancel()
return fmt.Errorf("reservation server not ready: %v",
timeOutCtx.Err())
case <-initChan:
cancel()
}
}
staticAddressManager.WaitInitComplete()

// Last, start our internal error handler. This will return exactly one
// error or nil on the main error channel to inform the caller that
Expand Down
2 changes: 2 additions & 0 deletions loopd/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/lightninglabs/loop/instantout/reservation"
"github.com/lightninglabs/loop/liquidity"
"github.com/lightninglabs/loop/loopdb"
"github.com/lightninglabs/loop/staticaddr"
"github.com/lightninglabs/loop/sweepbatcher"
"github.com/lightningnetwork/lnd"
"github.com/lightningnetwork/lnd/build"
Expand Down Expand Up @@ -37,6 +38,7 @@ func SetupLoggers(root *build.RotatingLogWriter, intercept signal.Interceptor) {
lnd.AddSubLogger(root, "SWEEP", intercept, sweepbatcher.UseLogger)
lnd.AddSubLogger(root, "LNDC", intercept, lndclient.UseLogger)
lnd.AddSubLogger(root, "STORE", intercept, loopdb.UseLogger)
lnd.AddSubLogger(root, "SADDR", intercept, staticaddr.UseLogger)
lnd.AddSubLogger(root, lsat.Subsystem, intercept, lsat.UseLogger)
lnd.AddSubLogger(
root, liquidity.Subsystem, intercept, liquidity.UseLogger,
Expand Down
7 changes: 7 additions & 0 deletions loopd/perms/perms.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ var RequiredPermissions = map[string][]bakery.Op{
Entity: "loop",
Action: "in",
}},
"/looprpc.StaticAddressClient/NewAddress": {{
Entity: "swap",
Action: "read",
}, {
Entity: "loop",
Action: "in",
}},
"/looprpc.SwapClient/GetLsatTokens": {{
Entity: "auth",
Action: "read",
Expand Down
1 change: 1 addition & 0 deletions loopdb/sqlc/migrations/000007_static_address.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE IF EXISTS static_addresses;
38 changes: 38 additions & 0 deletions loopdb/sqlc/migrations/000007_static_address.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
-- static_address stores the static loop-in addresses that clients
-- cooperatively created with the server.
CREATE TABLE IF NOT EXISTS static_addresses (
-- id is the auto-incrementing primary key for a static address.
id INTEGER PRIMARY KEY,

-- client_pubkey is the client side public taproot key that is used to
-- construct the 2-of-2 MuSig2 taproot output that represents the static
-- address.
client_pubkey BYTEA NOT NULL,

-- server_pubkey is the server side public taproot key that is used to
-- construct the 2-of-2 MuSig2 taproot output that represents the static
-- address.
server_pubkey BYTEA NOT NULL,

-- expiry denotes the CSV delay at which funds at a specific static address
-- can be swept back to the client.
expiry INT NOT NULL,

-- client_key_family is the key family of the client public key from the
-- client's lnd wallet.
client_key_family INT NOT NULL,

-- client_key_index is the key index of the client public key from the
-- client's lnd wallet.
client_key_index INT NOT NULL,

-- pkscript is the witness program that represents the static address. It is
-- unique amongst all static addresses.
pkscript BYTEA NOT NULL UNIQUE,

-- protocol_version is the protocol version that the swap was created with.
-- Note that this version is not upgraded if the client upgrades or
-- downgrades their protocol version for static address outputs already in
-- use.
protocol_version INTEGER NOT NULL
);
11 changes: 11 additions & 0 deletions loopdb/sqlc/models.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions loopdb/sqlc/querier.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions loopdb/sqlc/queries/static_addresses.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
-- name: AllStaticAddresses :many
SELECT * FROM static_addresses;

-- name: GetStaticAddress :one
SELECT * FROM static_addresses
WHERE pkscript=$1;

-- name: CreateStaticAddress :exec
INSERT INTO static_addresses (
client_pubkey,
server_pubkey,
expiry,
client_key_family,
client_key_index,
pkscript,
protocol_version
) VALUES (
$1,
$2,
$3,
$4,
$5,
$6,
$7
);
Loading

0 comments on commit d5cb601

Please sign in to comment.