mirror of
https://github.com/lightninglabs/loop.git
synced 2026-08-13 12:33:03 +02:00
staticaddr: cmd listdeposits and listswaps
This commit is contained in:
parent
a3f7fe44af
commit
439d178b96
11 changed files with 1717 additions and 183 deletions
|
|
@ -94,6 +94,20 @@ var RequiredPermissions = map[string][]bakery.Op{
|
|||
Entity: "loop",
|
||||
Action: "in",
|
||||
}},
|
||||
"/looprpc.SwapClient/ListStaticAddressDeposits": {{
|
||||
Entity: "swap",
|
||||
Action: "read",
|
||||
}, {
|
||||
Entity: "loop",
|
||||
Action: "in",
|
||||
}},
|
||||
"/looprpc.SwapClient/ListStaticAddressSwaps": {{
|
||||
Entity: "swap",
|
||||
Action: "read",
|
||||
}, {
|
||||
Entity: "loop",
|
||||
Action: "in",
|
||||
}},
|
||||
"/looprpc.SwapClient/GetStaticAddressSummary": {{
|
||||
Entity: "swap",
|
||||
Action: "read",
|
||||
|
|
|
|||
|
|
@ -763,11 +763,11 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context,
|
|||
}
|
||||
|
||||
// Retrieve deposits to calculate their total value.
|
||||
var summary *looprpc.StaticAddressSummaryResponse
|
||||
var depositList *looprpc.ListStaticAddressDepositsResponse
|
||||
amount := btcutil.Amount(req.Amt)
|
||||
if len(req.DepositOutpoints) > 0 {
|
||||
summary, err = s.GetStaticAddressSummary(
|
||||
ctx, &looprpc.StaticAddressSummaryRequest{
|
||||
depositList, err = s.ListStaticAddressDeposits(
|
||||
ctx, &looprpc.ListStaticAddressDepositsRequest{
|
||||
Outpoints: req.DepositOutpoints,
|
||||
},
|
||||
)
|
||||
|
|
@ -775,14 +775,14 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if summary == nil {
|
||||
if depositList == nil {
|
||||
return nil, fmt.Errorf("no summary returned for " +
|
||||
"deposit outpoints")
|
||||
}
|
||||
|
||||
// The requested amount should be 0 here if the request
|
||||
// contained deposit outpoints.
|
||||
if amount != 0 && len(summary.FilteredDeposits) > 0 {
|
||||
if amount != 0 && len(depositList.FilteredDeposits) > 0 {
|
||||
return nil, fmt.Errorf("amount should be 0 for " +
|
||||
"deposit quotes")
|
||||
}
|
||||
|
|
@ -790,8 +790,8 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context,
|
|||
// In case we quote for deposits we send the server both the
|
||||
// total value and the number of deposits. This is so the server
|
||||
// can probe the total amount and calculate the per input fee.
|
||||
if amount == 0 && len(summary.FilteredDeposits) > 0 {
|
||||
for _, deposit := range summary.FilteredDeposits {
|
||||
if amount == 0 && len(depositList.FilteredDeposits) > 0 {
|
||||
for _, deposit := range depositList.FilteredDeposits {
|
||||
amount += btcutil.Amount(deposit.Value)
|
||||
}
|
||||
}
|
||||
|
|
@ -1459,15 +1459,16 @@ func (s *swapClientServer) WithdrawDeposits(ctx context.Context,
|
|||
}, err
|
||||
}
|
||||
|
||||
// GetStaticAddressSummary returns a summary static address related information.
|
||||
// Amongst deposits and withdrawals and their total values it also includes a
|
||||
// list of detailed deposit information filtered by their state.
|
||||
func (s *swapClientServer) GetStaticAddressSummary(ctx context.Context,
|
||||
req *looprpc.StaticAddressSummaryRequest) (
|
||||
*looprpc.StaticAddressSummaryResponse, error) {
|
||||
// ListStaticAddressDeposits returns a list of all sufficiently confirmed
|
||||
// deposits behind the static address and displays properties like value,
|
||||
// state or blocks til expiry.
|
||||
func (s *swapClientServer) ListStaticAddressDeposits(ctx context.Context,
|
||||
req *looprpc.ListStaticAddressDepositsRequest) (
|
||||
*looprpc.ListStaticAddressDepositsResponse, error) {
|
||||
|
||||
outpoints := req.Outpoints
|
||||
if req.StateFilter != looprpc.DepositState_UNKNOWN_STATE &&
|
||||
len(req.Outpoints) > 0 {
|
||||
len(outpoints) > 0 {
|
||||
|
||||
return nil, fmt.Errorf("can either filter by state or " +
|
||||
"outpoints")
|
||||
|
|
@ -1478,9 +1479,181 @@ func (s *swapClientServer) GetStaticAddressSummary(ctx context.Context,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return s.depositSummary(
|
||||
ctx, allDeposits, req.StateFilter, req.Outpoints,
|
||||
// Deposits filtered by state or outpoints.
|
||||
var filteredDeposits []*looprpc.Deposit
|
||||
if len(outpoints) > 0 {
|
||||
f := func(d *deposit.Deposit) bool {
|
||||
for _, outpoint := range outpoints {
|
||||
if outpoint == d.OutPoint.String() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
filteredDeposits = filter(allDeposits, f)
|
||||
|
||||
if len(outpoints) != len(filteredDeposits) {
|
||||
return nil, fmt.Errorf("not all outpoints found in " +
|
||||
"deposits")
|
||||
}
|
||||
} else {
|
||||
f := func(d *deposit.Deposit) bool {
|
||||
if req.StateFilter == looprpc.DepositState_UNKNOWN_STATE {
|
||||
// Per default, we return deposits in all
|
||||
// states.
|
||||
return true
|
||||
}
|
||||
|
||||
return d.IsInState(toServerState(req.StateFilter))
|
||||
}
|
||||
filteredDeposits = filter(allDeposits, f)
|
||||
}
|
||||
|
||||
// Calculate the blocks until expiry for each deposit.
|
||||
lndInfo, err := s.lnd.Client.GetInfo(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bestBlockHeight := int64(lndInfo.BlockHeight)
|
||||
params, err := s.staticAddressManager.GetStaticAddressParameters(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(filteredDeposits); i++ {
|
||||
filteredDeposits[i].BlocksUntilExpiry =
|
||||
filteredDeposits[i].ConfirmationHeight +
|
||||
int64(params.Expiry) - bestBlockHeight
|
||||
}
|
||||
|
||||
return &looprpc.ListStaticAddressDepositsResponse{
|
||||
FilteredDeposits: filteredDeposits,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ListStaticAddressSwaps returns a list of all swaps that are currently pending
|
||||
// or previously succeeded.
|
||||
func (s *swapClientServer) ListStaticAddressSwaps(ctx context.Context,
|
||||
_ *looprpc.ListStaticAddressSwapsRequest) (
|
||||
*looprpc.ListStaticAddressSwapsResponse, error) {
|
||||
|
||||
swaps, err := s.staticLoopInManager.GetAllSwaps(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(swaps) == 0 {
|
||||
return &looprpc.ListStaticAddressSwapsResponse{}, nil
|
||||
}
|
||||
|
||||
var clientSwaps []*looprpc.StaticAddressLoopInSwap
|
||||
for _, swp := range swaps {
|
||||
chainParams, err := s.network.ChainParams()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting chain params")
|
||||
}
|
||||
swapPayReq, err := zpay32.Decode(swp.SwapInvoice, chainParams)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error decoding swap invoice: "+
|
||||
"%v", err)
|
||||
}
|
||||
swap := &looprpc.StaticAddressLoopInSwap{
|
||||
SwapHash: swp.SwapHash[:],
|
||||
DepositOutpoints: swp.DepositOutpoints,
|
||||
State: toClientStaticAddressLoopInState(
|
||||
swp.GetState(),
|
||||
),
|
||||
SwapAmountSatoshis: int64(swp.TotalDepositAmount()),
|
||||
PaymentRequestAmountSatoshis: int64(
|
||||
swapPayReq.MilliSat.ToSatoshis(),
|
||||
),
|
||||
}
|
||||
|
||||
clientSwaps = append(clientSwaps, swap)
|
||||
}
|
||||
|
||||
return &looprpc.ListStaticAddressSwapsResponse{
|
||||
Swaps: clientSwaps,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetStaticAddressSummary returns a summary static address related information.
|
||||
// Amongst deposits and withdrawals and their total values it also includes a
|
||||
// list of detailed deposit information filtered by their state.
|
||||
func (s *swapClientServer) GetStaticAddressSummary(ctx context.Context,
|
||||
_ *looprpc.StaticAddressSummaryRequest) (
|
||||
*looprpc.StaticAddressSummaryResponse, error) {
|
||||
|
||||
allDeposits, err := s.depositManager.GetAllDeposits(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var (
|
||||
totalNumDeposits = len(allDeposits)
|
||||
valueUnconfirmed int64
|
||||
valueDeposited int64
|
||||
valueExpired int64
|
||||
valueWithdrawn int64
|
||||
valueLoopedIn int64
|
||||
htlcTimeoutSwept int64
|
||||
)
|
||||
|
||||
// Value unconfirmed.
|
||||
utxos, err := s.staticAddressManager.ListUnspent(
|
||||
ctx, 0, deposit.MinConfs-1,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, u := range utxos {
|
||||
valueUnconfirmed += int64(u.Value)
|
||||
}
|
||||
|
||||
// Confirmed total values by category.
|
||||
for _, d := range allDeposits {
|
||||
value := int64(d.Value)
|
||||
switch d.GetState() {
|
||||
case deposit.Deposited:
|
||||
valueDeposited += value
|
||||
|
||||
case deposit.Expired:
|
||||
valueExpired += value
|
||||
|
||||
case deposit.Withdrawn:
|
||||
valueWithdrawn += value
|
||||
|
||||
case deposit.LoopedIn:
|
||||
valueLoopedIn += value
|
||||
|
||||
case deposit.HtlcTimeoutSwept:
|
||||
htlcTimeoutSwept += value
|
||||
}
|
||||
}
|
||||
|
||||
params, err := s.staticAddressManager.GetStaticAddressParameters(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
address, err := s.staticAddressManager.GetTaprootAddress(
|
||||
params.ClientPubkey, params.ServerPubkey, int64(params.Expiry),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &looprpc.StaticAddressSummaryResponse{
|
||||
StaticAddress: address.String(),
|
||||
RelativeExpiryBlocks: uint64(params.Expiry),
|
||||
TotalNumDeposits: uint32(totalNumDeposits),
|
||||
ValueUnconfirmedSatoshis: valueUnconfirmed,
|
||||
ValueDepositedSatoshis: valueDeposited,
|
||||
ValueExpiredSatoshis: valueExpired,
|
||||
ValueWithdrawnSatoshis: valueWithdrawn,
|
||||
ValueLoopedInSatoshis: valueLoopedIn,
|
||||
ValueHtlcTimeoutSweepsSatoshis: htlcTimeoutSwept,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// StaticAddressLoopIn initiates a loop-in request using static address
|
||||
|
|
@ -1534,108 +1707,6 @@ func (s *swapClientServer) StaticAddressLoopIn(ctx context.Context,
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (s *swapClientServer) depositSummary(ctx context.Context,
|
||||
deposits []*deposit.Deposit, stateFilter looprpc.DepositState,
|
||||
outpointsFilter []string) (*looprpc.StaticAddressSummaryResponse,
|
||||
error) {
|
||||
|
||||
var (
|
||||
totalNumDeposits = len(deposits)
|
||||
valueUnconfirmed int64
|
||||
valueDeposited int64
|
||||
valueExpired int64
|
||||
valueWithdrawn int64
|
||||
valueLoopedIn int64
|
||||
htlcTimeoutSwept int64
|
||||
)
|
||||
|
||||
// Value unconfirmed.
|
||||
utxos, err := s.staticAddressManager.ListUnspent(
|
||||
ctx, 0, deposit.MinConfs-1,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, u := range utxos {
|
||||
valueUnconfirmed += int64(u.Value)
|
||||
}
|
||||
|
||||
// Confirmed total values by category.
|
||||
for _, d := range deposits {
|
||||
value := int64(d.Value)
|
||||
switch d.GetState() {
|
||||
case deposit.Deposited:
|
||||
valueDeposited += value
|
||||
|
||||
case deposit.Expired:
|
||||
valueExpired += value
|
||||
|
||||
case deposit.Withdrawn:
|
||||
valueWithdrawn += value
|
||||
|
||||
case deposit.LoopedIn:
|
||||
valueLoopedIn += value
|
||||
|
||||
case deposit.HtlcTimeoutSwept:
|
||||
htlcTimeoutSwept += value
|
||||
}
|
||||
}
|
||||
|
||||
// Deposits filtered by state or outpoints.
|
||||
var clientDeposits []*looprpc.Deposit
|
||||
if len(outpointsFilter) > 0 {
|
||||
f := func(d *deposit.Deposit) bool {
|
||||
for _, outpoint := range outpointsFilter {
|
||||
if outpoint == d.OutPoint.String() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
clientDeposits = filter(deposits, f)
|
||||
|
||||
if len(outpointsFilter) != len(clientDeposits) {
|
||||
return nil, fmt.Errorf("not all outpoints found in " +
|
||||
"deposits")
|
||||
}
|
||||
} else {
|
||||
f := func(d *deposit.Deposit) bool {
|
||||
if stateFilter == looprpc.DepositState_UNKNOWN_STATE {
|
||||
// Per default, we return deposits in all
|
||||
// states.
|
||||
return true
|
||||
}
|
||||
|
||||
return d.IsInState(toServerState(stateFilter))
|
||||
}
|
||||
clientDeposits = filter(deposits, f)
|
||||
}
|
||||
|
||||
params, err := s.staticAddressManager.GetStaticAddressParameters(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
address, err := s.staticAddressManager.GetTaprootAddress(
|
||||
params.ClientPubkey, params.ServerPubkey, int64(params.Expiry),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &looprpc.StaticAddressSummaryResponse{
|
||||
StaticAddress: address.String(),
|
||||
TotalNumDeposits: uint32(totalNumDeposits),
|
||||
ValueUnconfirmedSatoshis: valueUnconfirmed,
|
||||
ValueDepositedSatoshis: valueDeposited,
|
||||
ValueExpiredSatoshis: valueExpired,
|
||||
ValueWithdrawnSatoshis: valueWithdrawn,
|
||||
ValueLoopedInSatoshis: valueLoopedIn,
|
||||
ValueHtlcTimeoutSweepsSatoshis: htlcTimeoutSwept,
|
||||
FilteredDeposits: clientDeposits,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type filterFunc func(deposits *deposit.Deposit) bool
|
||||
|
||||
func filter(deposits []*deposit.Deposit, f filterFunc) []*looprpc.Deposit {
|
||||
|
|
@ -1648,8 +1719,10 @@ func filter(deposits []*deposit.Deposit, f filterFunc) []*looprpc.Deposit {
|
|||
hash := d.Hash
|
||||
outpoint := wire.NewOutPoint(&hash, d.Index).String()
|
||||
deposit := &looprpc.Deposit{
|
||||
Id: d.ID[:],
|
||||
State: toClientState(d.GetState()),
|
||||
Id: d.ID[:],
|
||||
State: toClientDepositState(
|
||||
d.GetState(),
|
||||
),
|
||||
Outpoint: outpoint,
|
||||
Value: int64(d.Value),
|
||||
ConfirmationHeight: d.ConfirmationHeight,
|
||||
|
|
@ -1661,7 +1734,7 @@ func filter(deposits []*deposit.Deposit, f filterFunc) []*looprpc.Deposit {
|
|||
return clientDeposits
|
||||
}
|
||||
|
||||
func toClientState(state fsm.StateType) looprpc.DepositState {
|
||||
func toClientDepositState(state fsm.StateType) looprpc.DepositState {
|
||||
switch state {
|
||||
case deposit.Deposited:
|
||||
return looprpc.DepositState_DEPOSITED
|
||||
|
|
@ -1698,6 +1771,51 @@ func toClientState(state fsm.StateType) looprpc.DepositState {
|
|||
}
|
||||
}
|
||||
|
||||
func toClientStaticAddressLoopInState(
|
||||
state fsm.StateType) looprpc.StaticAddressLoopInSwapState {
|
||||
|
||||
switch state {
|
||||
case loopin.InitHtlcTx:
|
||||
return looprpc.StaticAddressLoopInSwapState_INIT_HTLC
|
||||
|
||||
case loopin.SignHtlcTx:
|
||||
return looprpc.StaticAddressLoopInSwapState_SIGN_HTLC_TX
|
||||
|
||||
case loopin.MonitorInvoiceAndHtlcTx:
|
||||
return looprpc.StaticAddressLoopInSwapState_MONITOR_INVOICE_HTLC_TX
|
||||
|
||||
case loopin.PaymentReceived:
|
||||
return looprpc.StaticAddressLoopInSwapState_PAYMENT_RECEIVED
|
||||
|
||||
case loopin.SweepHtlcTimeout:
|
||||
return looprpc.StaticAddressLoopInSwapState_SWEEP_STATIC_ADDRESS_HTLC_TIMEOUT
|
||||
|
||||
case loopin.MonitorHtlcTimeoutSweep:
|
||||
return looprpc.StaticAddressLoopInSwapState_MONITOR_HTLC_TIMEOUT_SWEEP
|
||||
|
||||
case loopin.HtlcTimeoutSwept:
|
||||
return looprpc.StaticAddressLoopInSwapState_HTLC_STATIC_ADDRESS_TIMEOUT_SWEPT
|
||||
|
||||
case loopin.FetchSignPushSweeplessSweepTx:
|
||||
return looprpc.StaticAddressLoopInSwapState_FETCH_SIGN_PUSH_SWEEPLESS_SWEEP_TX
|
||||
|
||||
case loopin.Succeeded:
|
||||
return looprpc.StaticAddressLoopInSwapState_SUCCEEDED
|
||||
|
||||
case loopin.SucceededSweeplessSigFailed:
|
||||
return looprpc.StaticAddressLoopInSwapState_SUCCEEDED_SWEEPLESS_SIG_FAILED
|
||||
|
||||
case loopin.UnlockDeposits:
|
||||
return looprpc.StaticAddressLoopInSwapState_UNLOCK_DEPOSITS
|
||||
|
||||
case loopin.Failed:
|
||||
return looprpc.StaticAddressLoopInSwapState_FAILED_STATIC_ADDRESS_SWAP
|
||||
|
||||
default:
|
||||
return looprpc.StaticAddressLoopInSwapState_UNKNOWN_STATIC_ADDRESS_SWAP_STATE
|
||||
}
|
||||
}
|
||||
|
||||
func toServerState(state looprpc.DepositState) fsm.StateType {
|
||||
switch state {
|
||||
case looprpc.DepositState_DEPOSITED:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue