loop/loopdb/swapstate.go
Boris Nagaev d554b42ef6
multi: migrate to btcd v2 modules
Update LND, Aperture, and Taproot Assets to revisions using the
btcd v2 modules, and update lndclient to v0.21.0-3. Migrate Loop
chain, transaction, and address types to their corresponding v2
packages.

The lndclient release includes the migration from:
https://github.com/lightninglabs/lndclient/pull/280

Taproot Assets is temporarily replaced with its btcd v2 revision
because the v0.8 release branch has not adopted the new modules.

This raises the minimum Go version to 1.26 and changes exported
address types.
2026-08-12 23:39:26 +00:00

200 lines
6 KiB
Go

package loopdb
import (
"github.com/btcsuite/btcd/btcutil/v2"
"github.com/btcsuite/btcd/chainhash/v2"
)
// SwapState indicates the current state of a swap. This enumeration is the
// union of loop in and loop out states. A single type is used for both swap
// types to be able to reduce code duplication that would otherwise be required.
type SwapState uint8
const (
// StateInitiated is the initial state of a swap. At that point, the
// initiation call to the server has been made and the payment process
// has been started for the swap and prepayment invoices.
StateInitiated SwapState = 0
// StatePreimageRevealed is reached when the sweep tx publication is
// first attempted. From that point on, we should consider the preimage
// to no longer be secret and we need to do all we can to get the sweep
// confirmed. This state will mostly coalesce with StateHtlcConfirmed,
// except in the case where we wait for fees to come down before we
// sweep.
StatePreimageRevealed SwapState = 1
// StateSuccess is the final swap state that is reached when the sweep
// tx has the required confirmation depth (SweepConfDepth) and the
// server pulled the off-chain htlc.
StateSuccess SwapState = 2
// StateFailOffchainPayments indicates that it wasn't possible to find
// routes for one or both of the off-chain payments to the server that
// satisfied the payment restrictions (fee and timelock limits).
StateFailOffchainPayments SwapState = 3
// StateFailTimeout indicates that the on-chain htlc wasn't confirmed
// before its expiry or confirmed too late (MinPreimageRevealDelta
// violated).
StateFailTimeout SwapState = 4
// StateFailSweepTimeout indicates that the on-chain htlc wasn't swept
// before the server revoked the htlc. The server didn't pull the
// off-chain htlc (even though it could have) and we timed out the
// off-chain htlc ourselves. No funds lost.
StateFailSweepTimeout SwapState = 5
// StateFailInsufficientValue indicates that the published on-chain htlc
// had a value lower than the requested amount.
StateFailInsufficientValue SwapState = 6
// StateFailTemporary indicates that the swap cannot progress because
// of an internal error. This is not a final state. Manual intervention
// (like a restart) is required to solve this problem.
StateFailTemporary SwapState = 7
// StateHtlcPublished means that the client published the on-chain htlc.
StateHtlcPublished SwapState = 8
// StateInvoiceSettled means that the swap invoice has been paid by the
// server.
StateInvoiceSettled SwapState = 9
// StateFailIncorrectHtlcAmt indicates that the amount of an externally
// published loop in htlc didn't match the swap amount.
StateFailIncorrectHtlcAmt SwapState = 10
// StateFailAbandoned indicates that a swap has been abandoned. Its
// execution has been canceled. It won't further be processed.
StateFailAbandoned SwapState = 11
// StateFailInsufficientConfirmedBalance indicates that the swap wasn't
// published due to insufficient confirmed balance.
StateFailInsufficientConfirmedBalance SwapState = 12
// StateFailIncorrectHtlcAmtSwept indicates that the amount of an
// externally published loop in htlc that didn't match the swap amount
// has been swept back to the user after the htlc timeout period.
StateFailIncorrectHtlcAmtSwept SwapState = 13
)
// SwapStateType defines the types of swap states that exist. Every swap state
// defined as type SwapState above, falls into one of these SwapStateType
// categories.
type SwapStateType uint8
const (
// StateTypePending indicates that the swap is still pending.
StateTypePending SwapStateType = 0
// StateTypeSuccess indicates that the swap has completed successfully.
StateTypeSuccess = 1
// StateTypeFail indicates that the swap has failed.
StateTypeFail = 2
)
// Type returns the type of the SwapState it is called on.
func (s SwapState) Type() SwapStateType {
if s.IsPending() {
return StateTypePending
}
if s == StateSuccess {
return StateTypeSuccess
}
return StateTypeFail
}
// IsPending returns true if the swap is in a pending state.
func (s SwapState) IsPending() bool {
return s == StateInitiated || s == StateHtlcPublished ||
s == StatePreimageRevealed || s == StateFailTemporary ||
s == StateInvoiceSettled || s == StateFailIncorrectHtlcAmt
}
// IsFinal returns true if the swap is in a final state.
func (s SwapState) IsFinal() bool {
return !s.IsPending()
}
// String returns a string representation of the swap's state.
func (s SwapState) String() string {
switch s {
case StateInitiated:
return "Initiated"
case StatePreimageRevealed:
return "PreimageRevealed"
case StateHtlcPublished:
return "HtlcPublished"
case StateSuccess:
return "Success"
case StateFailOffchainPayments:
return "FailOffchainPayments"
case StateFailTimeout:
return "FailTimeout"
case StateFailSweepTimeout:
return "FailSweepTimeout"
case StateFailInsufficientValue:
return "FailInsufficientValue"
case StateFailTemporary:
return "FailTemporary"
case StateInvoiceSettled:
return "InvoiceSettled"
case StateFailIncorrectHtlcAmt:
return "IncorrectHtlcAmt"
case StateFailAbandoned:
return "FailAbandoned"
case StateFailInsufficientConfirmedBalance:
return "InsufficientConfirmedBalance"
case StateFailIncorrectHtlcAmtSwept:
return "StateFailIncorrectHtlcAmtSwept"
default:
return "Unknown"
}
}
// SwapCost is a breakdown of the final swap costs.
type SwapCost struct {
// Server is the amount paid to the server.
Server btcutil.Amount
// Onchain is the amount paid to miners for the onchain tx.
Onchain btcutil.Amount
// Offchain is the amount paid in routing fees.
Offchain btcutil.Amount
}
// Total returns the total costs represented by swap costs.
func (s SwapCost) Total() btcutil.Amount {
return s.Server + s.Onchain + s.Offchain
}
// SwapStateData is all persistent data to describe the current swap state.
type SwapStateData struct {
// State is the state the swap is in.
State SwapState
// Cost are the accrued (final) costs so far.
Cost SwapCost
// HtlcTxHash is the tx id of the confirmed htlc.
HtlcTxHash *chainhash.Hash
}