staticaddr: deposits for server and daemon

Slyghtning 2 months ago
parent 4b012b6988
commit 1917e788a9
No known key found for this signature in database
GPG Key ID: F82D456EA023C9BF

@ -21,7 +21,8 @@ import (
"github.com/lightninglabs/loop/loopd/perms" "github.com/lightninglabs/loop/loopd/perms"
"github.com/lightninglabs/loop/loopdb" "github.com/lightninglabs/loop/loopdb"
loop_looprpc "github.com/lightninglabs/loop/looprpc" loop_looprpc "github.com/lightninglabs/loop/looprpc"
"github.com/lightninglabs/loop/staticaddr" "github.com/lightninglabs/loop/staticaddr/address"
"github.com/lightninglabs/loop/staticaddr/deposit"
loop_swaprpc "github.com/lightninglabs/loop/swapserverrpc" loop_swaprpc "github.com/lightninglabs/loop/swapserverrpc"
"github.com/lightninglabs/loop/sweepbatcher" "github.com/lightninglabs/loop/sweepbatcher"
"github.com/lightningnetwork/lnd/clock" "github.com/lightningnetwork/lnd/clock"
@ -68,12 +69,6 @@ type Daemon struct {
// same process. // same process.
swapClientServer 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 // ErrChan is an error channel that users of the Daemon struct must use
// to detect runtime errors and also whether a shutdown is fully // to detect runtime errors and also whether a shutdown is fully
// completed. // completed.
@ -239,7 +234,6 @@ func (d *Daemon) startWebServers() error {
grpc.StreamInterceptor(streamInterceptor), grpc.StreamInterceptor(streamInterceptor),
) )
loop_looprpc.RegisterSwapClientServer(d.grpcServer, d) loop_looprpc.RegisterSwapClientServer(d.grpcServer, d)
loop_looprpc.RegisterStaticAddressClientServer(d.grpcServer, d)
// Register our debug server if it is compiled in. // Register our debug server if it is compiled in.
d.registerDebugServer() d.registerDebugServer()
@ -438,6 +432,11 @@ func (d *Daemon) initialize(withMacaroonService bool) error {
swapClient.Conn, swapClient.Conn,
) )
// Create a static address server client.
staticAddressClient := loop_swaprpc.NewStaticAddressServerClient(
swapClient.Conn,
)
// Both the client RPC server and the swap server client should stop // Both the client RPC server and the swap server client should stop
// on main context cancel. So we create it early and pass it down. // on main context cancel. So we create it early and pass it down.
d.mainCtx, d.mainCtxCancel = context.WithCancel(context.Background()) d.mainCtx, d.mainCtxCancel = context.WithCancel(context.Background())
@ -498,6 +497,9 @@ func (d *Daemon) initialize(withMacaroonService bool) error {
var ( var (
reservationManager *reservation.Manager reservationManager *reservation.Manager
instantOutManager *instantout.Manager instantOutManager *instantout.Manager
staticAddressManager *address.Manager
depositManager *deposit.Manager
) )
// Create the reservation and instantout managers. // Create the reservation and instantout managers.
if d.cfg.EnableExperimental { if d.cfg.EnableExperimental {
@ -534,43 +536,50 @@ func (d *Daemon) initialize(withMacaroonService bool) error {
instantOutManager = instantout.NewInstantOutManager( instantOutManager = instantout.NewInstantOutManager(
instantOutConfig, instantOutConfig,
) )
// Static address manager setup.
staticAddressStore := address.NewSqlStore(baseDb)
addrCfg := &address.ManagerConfig{
AddressClient: staticAddressClient,
FetchL402: swapClient.Server.FetchL402,
Store: staticAddressStore,
WalletKit: d.lnd.WalletKit,
ChainParams: d.lnd.ChainParams,
}
staticAddressManager = address.NewManager(addrCfg)
// Static address deposit manager setup.
depositStore := deposit.NewSqlStore(baseDb)
depoCfg := &deposit.ManagerConfig{
AddressClient: staticAddressClient,
AddressManager: staticAddressManager,
SwapClient: swapClient,
Store: depositStore,
WalletKit: d.lnd.WalletKit,
ChainParams: d.lnd.ChainParams,
ChainNotifier: d.lnd.ChainNotifier,
Signer: d.lnd.Signer,
}
depositManager = deposit.NewManager(depoCfg)
} }
// Now finally fully initialize the swap client RPC server instance. // Now finally fully initialize the swap client RPC server instance.
d.swapClientServer = swapClientServer{ d.swapClientServer = swapClientServer{
config: d.cfg, config: d.cfg,
network: lndclient.Network(d.cfg.Network), network: lndclient.Network(d.cfg.Network),
impl: swapClient, impl: swapClient,
liquidityMgr: getLiquidityManager(swapClient), liquidityMgr: getLiquidityManager(swapClient),
lnd: &d.lnd.LndServices, lnd: &d.lnd.LndServices,
swaps: make(map[lntypes.Hash]loop.SwapInfo), swaps: make(map[lntypes.Hash]loop.SwapInfo),
subscribers: make(map[int]chan<- interface{}), subscribers: make(map[int]chan<- interface{}),
statusChan: make(chan loop.SwapInfo), statusChan: make(chan loop.SwapInfo),
mainCtx: d.mainCtx, mainCtx: d.mainCtx,
reservationManager: reservationManager, reservationManager: reservationManager,
instantOutManager: instantOutManager, instantOutManager: instantOutManager,
staticAddressManager: staticAddressManager,
depositManager: depositManager,
} }
// 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. // Retrieve all currently existing swaps from the database.
swapsList, err := d.impl.FetchSwaps(d.mainCtx) swapsList, err := d.impl.FetchSwaps(d.mainCtx)
if err != nil { if err != nil {
@ -662,20 +671,43 @@ func (d *Daemon) initialize(withMacaroonService bool) error {
} }
// Start the static address manager. // Start the static address manager.
d.wg.Add(1) if staticAddressManager != nil {
go func() { d.wg.Add(1)
defer d.wg.Done() go func() {
defer d.wg.Done()
log.Info("Starting static address manager...") log.Info("Starting static address manager...")
err = staticAddressManager.Run(d.mainCtx) err = staticAddressManager.Run(d.mainCtx)
if err != nil && !errors.Is(context.Canceled, err) { if err != nil && !errors.Is(context.Canceled, err) {
d.internalErrChan <- err d.internalErrChan <- err
} }
log.Info("Static address manager stopped")
}()
}
log.Info("Static address manager stopped") // Start the static address deposit manager.
}() if depositManager != nil {
d.wg.Add(1)
go func() {
defer d.wg.Done()
staticAddressManager.WaitInitComplete() // Lnd's GetInfo call supplies us with the current block
// height.
info, err := d.lnd.Client.GetInfo(d.mainCtx)
if err != nil {
d.internalErrChan <- err
return
}
log.Info("Starting static address deposit manager...")
err = depositManager.Run(d.mainCtx, info.BlockHeight)
if err != nil && !errors.Is(context.Canceled, err) {
d.internalErrChan <- err
}
log.Info("Static address deposit manager stopped")
}()
depositManager.WaitInitComplete()
}
// Last, start our internal error handler. This will return exactly one // Last, start our internal error handler. This will return exactly one
// error or nil on the main error channel to inform the caller that // error or nil on the main error channel to inform the caller that

@ -69,14 +69,14 @@ var RequiredPermissions = map[string][]bakery.Op{
Entity: "loop", Entity: "loop",
Action: "in", Action: "in",
}}, }},
"/looprpc.StaticAddressClient/NewAddress": {{ "/looprpc.SwapClient/NewStaticAddress": {{
Entity: "swap", Entity: "swap",
Action: "read", Action: "read",
}, { }, {
Entity: "loop", Entity: "loop",
Action: "in", Action: "in",
}}, }},
"/looprpc.StaticAddressClient/ListUnspent": {{ "/looprpc.SwapClient/ListUnspentDeposits": {{
Entity: "swap", Entity: "swap",
Action: "read", Action: "read",
}, { }, {

@ -24,6 +24,8 @@ import (
"github.com/lightninglabs/loop/liquidity" "github.com/lightninglabs/loop/liquidity"
"github.com/lightninglabs/loop/loopdb" "github.com/lightninglabs/loop/loopdb"
clientrpc "github.com/lightninglabs/loop/looprpc" clientrpc "github.com/lightninglabs/loop/looprpc"
"github.com/lightninglabs/loop/staticaddr/address"
"github.com/lightninglabs/loop/staticaddr/deposit"
"github.com/lightninglabs/loop/swap" "github.com/lightninglabs/loop/swap"
looprpc "github.com/lightninglabs/loop/swapserverrpc" looprpc "github.com/lightninglabs/loop/swapserverrpc"
"github.com/lightningnetwork/lnd/lnrpc/walletrpc" "github.com/lightningnetwork/lnd/lnrpc/walletrpc"
@ -76,19 +78,21 @@ type swapClientServer struct {
clientrpc.UnimplementedSwapClientServer clientrpc.UnimplementedSwapClientServer
clientrpc.UnimplementedDebugServer clientrpc.UnimplementedDebugServer
config *Config config *Config
network lndclient.Network network lndclient.Network
impl *loop.Client impl *loop.Client
liquidityMgr *liquidity.Manager liquidityMgr *liquidity.Manager
lnd *lndclient.LndServices lnd *lndclient.LndServices
reservationManager *reservation.Manager reservationManager *reservation.Manager
instantOutManager *instantout.Manager instantOutManager *instantout.Manager
swaps map[lntypes.Hash]loop.SwapInfo staticAddressManager *address.Manager
subscribers map[int]chan<- interface{} depositManager *deposit.Manager
statusChan chan loop.SwapInfo swaps map[lntypes.Hash]loop.SwapInfo
nextSubscriberID int subscribers map[int]chan<- interface{}
swapsLock sync.Mutex statusChan chan loop.SwapInfo
mainCtx context.Context nextSubscriberID int
swapsLock sync.Mutex
mainCtx context.Context
} }
// LoopOut initiates a loop out swap with the given parameters. The call returns // LoopOut initiates a loop out swap with the given parameters. The call returns
@ -1272,6 +1276,51 @@ func rpcInstantOut(instantOut *instantout.InstantOut) *clientrpc.InstantOut {
} }
} }
// NewStaticAddress is the rpc endpoint for loop clients to request a new static
// address.
func (s *swapClientServer) NewStaticAddress(ctx context.Context,
_ *clientrpc.NewStaticAddressRequest) (
*clientrpc.NewStaticAddressResponse, error) {
staticAddress, err := s.staticAddressManager.NewAddress(ctx)
if err != nil {
return nil, err
}
return &clientrpc.NewStaticAddressResponse{
Address: staticAddress.String(),
}, nil
}
// ListUnspentDeposits returns a list of utxos behind the static address.
func (s *swapClientServer) ListUnspentDeposits(ctx context.Context,
req *clientrpc.ListUnspentDepositsRequest) (
*clientrpc.ListUnspentDepositsResponse, error) {
// List all unspent utxos the wallet sees, regardless of the number of
// confirmations.
staticAddress, utxos, err := s.staticAddressManager.ListUnspentRaw(
ctx, req.MinConfs, req.MaxConfs,
)
if err != nil {
return nil, err
}
// Prepare the list response.
var respUtxos []*clientrpc.Utxo
for _, u := range utxos {
utxo := &clientrpc.Utxo{
StaticAddress: staticAddress.String(),
AmountSat: int64(u.Value),
Confirmations: u.Confirmations,
Outpoint: u.OutPoint.String(),
}
respUtxos = append(respUtxos, utxo)
}
return &clientrpc.ListUnspentDepositsResponse{Utxos: respUtxos}, nil
}
func rpcAutoloopReason(reason liquidity.Reason) (clientrpc.AutoReason, error) { func rpcAutoloopReason(reason liquidity.Reason) (clientrpc.AutoReason, error) {
switch reason { switch reason {
case liquidity.ReasonNone: case liquidity.ReasonNone:

@ -1,70 +0,0 @@
package staticaddr
import (
"context"
"github.com/lightninglabs/loop/looprpc"
staticaddressrpc "github.com/lightninglabs/loop/swapserverrpc"
)
// AddressServer holds all fields for the address rpc server.
type AddressServer struct {
addressClient staticaddressrpc.StaticAddressServerClient
manager *Manager
looprpc.UnimplementedStaticAddressClientServer
}
// NewAddressServer creates a new static address server.
func NewAddressServer(addressClient staticaddressrpc.StaticAddressServerClient,
manager *Manager) *AddressServer {
return &AddressServer{
addressClient: addressClient,
manager: manager,
}
}
// NewAddress is the rpc endpoint for loop clients to request a new static
// address.
func (s *AddressServer) NewAddress(ctx context.Context,
_ *looprpc.NewAddressRequest) (*looprpc.NewAddressResponse, error) {
address, err := s.manager.NewAddress(ctx)
if err != nil {
return nil, err
}
log.Infof("New static loop-in address: %s\n", address.String())
return &looprpc.NewAddressResponse{
Address: address.String(),
}, nil
}
// ListUnspent returns a list of utxos behind the static address.
func (s *AddressServer) ListUnspent(ctx context.Context,
req *looprpc.ListUnspentRequest) (*looprpc.ListUnspentResponse, error) {
// List all unspent utxos the wallet sees, regardless of the number of
// confirmations.
staticAddress, utxos, err := s.manager.ListUnspentRaw(
ctx, req.MinConfs, req.MaxConfs,
)
if err != nil {
return nil, err
}
// Prepare the list response.
var respUtxos []*looprpc.Utxo
for _, u := range utxos {
utxo := &looprpc.Utxo{
StaticAddress: staticAddress.String(),
AmountSat: int64(u.Value),
Confirmations: u.Confirmations,
Outpoint: u.OutPoint.String(),
}
respUtxos = append(respUtxos, utxo)
}
return &looprpc.ListUnspentResponse{Utxos: respUtxos}, nil
}
Loading…
Cancel
Save