2
0
mirror of https://github.com/lightninglabs/loop synced 2024-11-09 19:10:47 +00:00
loop/loopdb/swapstate.go

201 lines
6.0 KiB
Go

package loopdb
import (
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg/chainhash"
)
// 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 {
// Swap 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 {
// SwapState 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
}