mirror of
https://github.com/lightninglabs/loop.git
synced 2026-08-13 12:33:03 +02:00
Treat lnd wallet view as the source of spendable static-address outputs while keeping historical deposit records in the DB. Reconcile active FSMs against the current wallet view and reactivate known deposits when their outpoints are visible again. Refresh deposits before selection, withdrawal, loop-in, and channel-open paths, and filter list and summary responses through the live active set so stale Deposited records are not exposed as available funds.
148 lines
3.4 KiB
Go
148 lines
3.4 KiB
Go
package deposit
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"fmt"
|
|
"sync"
|
|
|
|
"github.com/btcsuite/btcd/btcutil"
|
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
|
"github.com/btcsuite/btcd/wire"
|
|
"github.com/lightninglabs/loop/fsm"
|
|
"github.com/lightningnetwork/lnd/lntypes"
|
|
)
|
|
|
|
// ID is a unique identifier for a deposit.
|
|
type ID [IdLength]byte
|
|
|
|
// FromByteSlice creates a deposit id from a byte slice.
|
|
func (r *ID) FromByteSlice(b []byte) error {
|
|
if len(b) != IdLength {
|
|
return fmt.Errorf("deposit id must be 32 bytes, got %d, %x",
|
|
len(b), b)
|
|
}
|
|
|
|
copy(r[:], b)
|
|
|
|
return nil
|
|
}
|
|
|
|
// Deposit bundles an utxo at a static address together with manager-relevant
|
|
// data.
|
|
//
|
|
// Lock order: if both Manager.mu and a Deposit lock are needed, acquire
|
|
// Manager.mu before Deposit.Lock. Never acquire Manager.mu while holding a
|
|
// Deposit lock.
|
|
//
|
|
// The state and ConfirmationHeight fields are mutable and protected by the
|
|
// deposit lock.
|
|
type Deposit struct {
|
|
sync.Mutex
|
|
|
|
// Outpoint of the deposit.
|
|
wire.OutPoint
|
|
|
|
// ID is the unique identifier of the deposit.
|
|
ID ID
|
|
|
|
// state is the current state of the deposit.
|
|
state fsm.StateType
|
|
|
|
// Value is the amount of the deposit.
|
|
Value btcutil.Amount
|
|
|
|
// ConfirmationHeight is the absolute height at which the deposit was
|
|
// first confirmed. A value of zero means the deposit is still
|
|
// unconfirmed.
|
|
ConfirmationHeight int64
|
|
|
|
// TimeOutSweepPkScript is the pk script that is used to sweep the
|
|
// deposit to after it is expired.
|
|
TimeOutSweepPkScript []byte
|
|
|
|
// ExpirySweepTxid is the transaction id of the expiry sweep.
|
|
ExpirySweepTxid chainhash.Hash
|
|
|
|
// SwapHash is an optional reference to a static address loop-in swap
|
|
// that used this deposit.
|
|
SwapHash *lntypes.Hash
|
|
|
|
// FinalizedWithdrawalTx is the coop-signed withdrawal transaction. It
|
|
// is republished on new block arrivals and on client restarts.
|
|
FinalizedWithdrawalTx *wire.MsgTx
|
|
}
|
|
|
|
// IsInFinalState returns true if the deposit is final.
|
|
func (d *Deposit) IsInFinalState() bool {
|
|
d.Lock()
|
|
defer d.Unlock()
|
|
|
|
return d.isInFinalStateNoLock()
|
|
}
|
|
|
|
func (d *Deposit) isInFinalStateNoLock() bool {
|
|
return d.state == Expired || d.state == Withdrawn ||
|
|
d.state == LoopedIn || d.state == HtlcTimeoutSwept ||
|
|
d.state == ChannelPublished
|
|
}
|
|
|
|
func (d *Deposit) IsExpired(currentHeight, expiry uint32) bool {
|
|
d.Lock()
|
|
defer d.Unlock()
|
|
|
|
if d.ConfirmationHeight <= 0 {
|
|
return false
|
|
}
|
|
|
|
return currentHeight >= uint32(d.ConfirmationHeight)+expiry
|
|
}
|
|
|
|
// GetConfirmationHeight returns the deposit confirmation height.
|
|
func (d *Deposit) GetConfirmationHeight() int64 {
|
|
d.Lock()
|
|
defer d.Unlock()
|
|
|
|
return d.ConfirmationHeight
|
|
}
|
|
|
|
// GetConfirmationHeightNoLock returns the deposit confirmation height without
|
|
// acquiring the deposit lock.
|
|
func (d *Deposit) GetConfirmationHeightNoLock() int64 {
|
|
return d.ConfirmationHeight
|
|
}
|
|
|
|
func (d *Deposit) GetState() fsm.StateType {
|
|
d.Lock()
|
|
defer d.Unlock()
|
|
|
|
return d.state
|
|
}
|
|
|
|
func (d *Deposit) SetState(state fsm.StateType) {
|
|
d.Lock()
|
|
defer d.Unlock()
|
|
|
|
d.state = state
|
|
}
|
|
|
|
func (d *Deposit) SetStateNoLock(state fsm.StateType) {
|
|
d.state = state
|
|
}
|
|
|
|
func (d *Deposit) IsInState(state fsm.StateType) bool {
|
|
d.Lock()
|
|
defer d.Unlock()
|
|
|
|
return d.state == state
|
|
}
|
|
|
|
func (d *Deposit) IsInStateNoLock(state fsm.StateType) bool {
|
|
return d.state == state
|
|
}
|
|
|
|
// GetRandomDepositID generates a random deposit ID.
|
|
func GetRandomDepositID() (ID, error) {
|
|
var id ID
|
|
_, err := rand.Read(id[:])
|
|
return id, err
|
|
}
|