2019-03-07 02:19:57 +00:00
|
|
|
package loopdb
|
2019-03-06 20:13:50 +00:00
|
|
|
|
2020-06-23 09:42:12 +00:00
|
|
|
import (
|
2022-03-14 12:36:02 +00:00
|
|
|
"github.com/btcsuite/btcd/btcutil"
|
2020-06-23 09:42:12 +00:00
|
|
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
|
|
|
)
|
2019-05-15 12:01:27 +00:00
|
|
|
|
2019-03-12 15:09:57 +00:00
|
|
|
// 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.
|
2019-03-06 20:13:50 +00:00
|
|
|
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.
|
2019-03-07 02:19:57 +00:00
|
|
|
StateInitiated SwapState = 0
|
2019-03-06 20:13:50 +00:00
|
|
|
|
|
|
|
// 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.
|
2020-06-23 10:35:22 +00:00
|
|
|
StatePreimageRevealed SwapState = 1
|
2019-03-06 20:13:50 +00:00
|
|
|
|
|
|
|
// 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.
|
2020-06-23 10:35:22 +00:00
|
|
|
StateSuccess SwapState = 2
|
2019-03-06 20:13:50 +00:00
|
|
|
|
2019-03-12 15:09:57 +00:00
|
|
|
// StateFailOffchainPayments indicates that it wasn't possible to find
|
|
|
|
// routes for one or both of the off-chain payments to the server that
|
2019-03-06 20:13:50 +00:00
|
|
|
// satisfied the payment restrictions (fee and timelock limits).
|
2020-06-23 10:35:22 +00:00
|
|
|
StateFailOffchainPayments SwapState = 3
|
2019-03-06 20:13:50 +00:00
|
|
|
|
2019-03-12 15:09:57 +00:00
|
|
|
// StateFailTimeout indicates that the on-chain htlc wasn't confirmed
|
|
|
|
// before its expiry or confirmed too late (MinPreimageRevealDelta
|
|
|
|
// violated).
|
2020-06-23 10:35:22 +00:00
|
|
|
StateFailTimeout SwapState = 4
|
2019-03-06 20:13:50 +00:00
|
|
|
|
2019-03-12 15:09:57 +00:00
|
|
|
// 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.
|
2020-06-23 10:35:22 +00:00
|
|
|
StateFailSweepTimeout SwapState = 5
|
2019-03-06 20:13:50 +00:00
|
|
|
|
2019-03-12 15:09:57 +00:00
|
|
|
// StateFailInsufficientValue indicates that the published on-chain htlc
|
|
|
|
// had a value lower than the requested amount.
|
2020-06-23 10:35:22 +00:00
|
|
|
StateFailInsufficientValue SwapState = 6
|
2019-03-06 20:13:50 +00:00
|
|
|
|
|
|
|
// 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.
|
2020-06-23 10:35:22 +00:00
|
|
|
StateFailTemporary SwapState = 7
|
2019-03-06 20:13:50 +00:00
|
|
|
|
|
|
|
// StateHtlcPublished means that the client published the on-chain htlc.
|
2020-06-23 10:35:22 +00:00
|
|
|
StateHtlcPublished SwapState = 8
|
2019-04-02 08:51:51 +00:00
|
|
|
|
|
|
|
// StateInvoiceSettled means that the swap invoice has been paid by the
|
|
|
|
// server.
|
2020-06-23 10:35:22 +00:00
|
|
|
StateInvoiceSettled SwapState = 9
|
2020-06-25 11:55:27 +00:00
|
|
|
|
|
|
|
// StateFailIncorrectHtlcAmt indicates that the amount of an externally
|
|
|
|
// published loop in htlc didn't match the swap amount.
|
|
|
|
StateFailIncorrectHtlcAmt SwapState = 10
|
2023-11-13 13:49:03 +00:00
|
|
|
|
|
|
|
// StateFailAbandoned indicates that a swap has been abandoned. Its
|
|
|
|
// execution has been canceled. It won't further be processed.
|
|
|
|
StateFailAbandoned SwapState = 11
|
2023-11-27 12:46:18 +00:00
|
|
|
|
|
|
|
// StateFailInsufficientConfirmedBalance indicates that the swap wasn't
|
|
|
|
// published due to insufficient confirmed balance.
|
|
|
|
StateFailInsufficientConfirmedBalance SwapState = 12
|
2024-01-12 10:35:42 +00:00
|
|
|
|
|
|
|
// 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
|
2019-03-07 02:19:57 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// 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
|
2019-03-06 20:13:50 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Type returns the type of the SwapState it is called on.
|
|
|
|
func (s SwapState) Type() SwapStateType {
|
2024-01-12 10:35:42 +00:00
|
|
|
if s.IsPending() {
|
2019-03-06 20:13:50 +00:00
|
|
|
return StateTypePending
|
|
|
|
}
|
|
|
|
|
|
|
|
if s == StateSuccess {
|
|
|
|
return StateTypeSuccess
|
|
|
|
}
|
|
|
|
|
|
|
|
return StateTypeFail
|
|
|
|
}
|
|
|
|
|
2023-11-13 13:49:03 +00:00
|
|
|
// 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 ||
|
2024-01-12 10:35:42 +00:00
|
|
|
s == StateInvoiceSettled || s == StateFailIncorrectHtlcAmt
|
2023-11-13 13:49:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// IsFinal returns true if the swap is in a final state.
|
|
|
|
func (s SwapState) IsFinal() bool {
|
|
|
|
return !s.IsPending()
|
|
|
|
}
|
|
|
|
|
2019-03-07 02:19:57 +00:00
|
|
|
// String returns a string representation of the swap's state.
|
2019-03-06 20:13:50 +00:00
|
|
|
func (s SwapState) String() string {
|
|
|
|
switch s {
|
|
|
|
case StateInitiated:
|
|
|
|
return "Initiated"
|
2019-03-07 02:19:57 +00:00
|
|
|
|
2019-03-06 20:13:50 +00:00
|
|
|
case StatePreimageRevealed:
|
|
|
|
return "PreimageRevealed"
|
2019-03-07 02:19:57 +00:00
|
|
|
|
2019-03-12 15:09:57 +00:00
|
|
|
case StateHtlcPublished:
|
|
|
|
return "HtlcPublished"
|
|
|
|
|
2019-03-06 20:13:50 +00:00
|
|
|
case StateSuccess:
|
|
|
|
return "Success"
|
2019-03-07 02:19:57 +00:00
|
|
|
|
2019-03-06 20:13:50 +00:00
|
|
|
case StateFailOffchainPayments:
|
|
|
|
return "FailOffchainPayments"
|
2019-03-07 02:19:57 +00:00
|
|
|
|
2019-03-06 20:13:50 +00:00
|
|
|
case StateFailTimeout:
|
|
|
|
return "FailTimeout"
|
2019-03-07 02:19:57 +00:00
|
|
|
|
2019-03-06 20:13:50 +00:00
|
|
|
case StateFailSweepTimeout:
|
|
|
|
return "FailSweepTimeout"
|
2019-03-07 02:19:57 +00:00
|
|
|
|
2019-03-06 20:13:50 +00:00
|
|
|
case StateFailInsufficientValue:
|
|
|
|
return "FailInsufficientValue"
|
2019-03-07 02:19:57 +00:00
|
|
|
|
2019-03-06 20:13:50 +00:00
|
|
|
case StateFailTemporary:
|
|
|
|
return "FailTemporary"
|
2019-03-07 02:19:57 +00:00
|
|
|
|
2019-04-02 08:51:51 +00:00
|
|
|
case StateInvoiceSettled:
|
|
|
|
return "InvoiceSettled"
|
|
|
|
|
2020-06-25 11:55:27 +00:00
|
|
|
case StateFailIncorrectHtlcAmt:
|
|
|
|
return "IncorrectHtlcAmt"
|
|
|
|
|
2023-11-13 13:49:03 +00:00
|
|
|
case StateFailAbandoned:
|
|
|
|
return "FailAbandoned"
|
|
|
|
|
2023-11-27 12:46:18 +00:00
|
|
|
case StateFailInsufficientConfirmedBalance:
|
|
|
|
return "InsufficientConfirmedBalance"
|
|
|
|
|
2024-01-12 10:35:42 +00:00
|
|
|
case StateFailIncorrectHtlcAmtSwept:
|
|
|
|
return "StateFailIncorrectHtlcAmtSwept"
|
|
|
|
|
2019-03-06 20:13:50 +00:00
|
|
|
default:
|
|
|
|
return "Unknown"
|
|
|
|
}
|
|
|
|
}
|
2019-05-15 11:55:41 +00:00
|
|
|
|
2019-05-15 12:01:27 +00:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
2020-10-12 11:34:54 +00:00
|
|
|
// Total returns the total costs represented by swap costs.
|
|
|
|
func (s SwapCost) Total() btcutil.Amount {
|
|
|
|
return s.Server + s.Onchain + s.Offchain
|
|
|
|
}
|
|
|
|
|
2019-05-15 11:55:41 +00:00
|
|
|
// SwapStateData is all persistent data to describe the current swap state.
|
|
|
|
type SwapStateData struct {
|
2019-05-15 12:01:27 +00:00
|
|
|
// SwapState is the state the swap is in.
|
2019-05-15 11:55:41 +00:00
|
|
|
State SwapState
|
2019-05-15 12:01:27 +00:00
|
|
|
|
|
|
|
// Cost are the accrued (final) costs so far.
|
|
|
|
Cost SwapCost
|
2020-06-23 09:42:12 +00:00
|
|
|
|
|
|
|
// HtlcTxHash is the tx id of the confirmed htlc.
|
|
|
|
HtlcTxHash *chainhash.Hash
|
2019-05-15 11:55:41 +00:00
|
|
|
}
|