contractcourt

package
v0.17.5-beta Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 19, 2024 License: MIT Imports: 37 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// NoAction is the min chainAction type, indicating that no action
	// needs to be taken for a given HTLC.
	NoAction ChainAction = 0

	// HtlcTimeoutAction indicates that the HTLC will timeout soon. As a
	// result, we should get ready to sweep it on chain after the timeout.
	HtlcTimeoutAction = 1

	// HtlcClaimAction indicates that we should claim the HTLC on chain
	// before its timeout period.
	HtlcClaimAction = 2

	// HtlcFailNowAction indicates that we should fail an outgoing HTLC
	// immediately by cancelling it backwards as it has no corresponding
	// output in our commitment transaction.
	HtlcFailNowAction = 3

	// HtlcOutgoingWatchAction indicates that we can't yet timeout this
	// HTLC, but we had to go to chain on order to resolve an existing
	// HTLC.  In this case, we'll either: time it out once it expires, or
	// will learn the pre-image if the remote party claims the output. In
	// this case, well add the pre-image to our global store.
	HtlcOutgoingWatchAction = 4

	// HtlcIncomingWatchAction indicates that we don't yet have the
	// pre-image to claim incoming HTLC, but we had to go to chain in order
	// to resolve and existing HTLC. In this case, we'll either: let the
	// other party time it out, or eventually learn of the pre-image, in
	// which case we'll claim on chain.
	HtlcIncomingWatchAction = 5

	// HtlcIncomingDustFinalAction indicates that we should mark an incoming
	// dust htlc as final because it can't be claimed on-chain.
	HtlcIncomingDustFinalAction = 6
)

Variables

View Source
var (
	// LocalHtlcSet is the HtlcSetKey used for local commitments.
	LocalHtlcSet = HtlcSetKey{IsRemote: false, IsPending: false}

	// RemoteHtlcSet is the HtlcSetKey used for remote commitments.
	RemoteHtlcSet = HtlcSetKey{IsRemote: true, IsPending: false}

	// RemotePendingHtlcSet is the HtlcSetKey used for dangling remote
	// commitment transactions.
	RemotePendingHtlcSet = HtlcSetKey{IsRemote: true, IsPending: true}
)
View Source
var ErrChainArbExiting = errors.New("ChainArbitrator exiting")

ErrChainArbExiting signals that the chain arbitrator is shutting down.

View Source
var (
	// ErrContractNotFound is returned when the nursery is unable to
	// retrieve information about a queried contract.
	ErrContractNotFound = fmt.Errorf("unable to locate contract")
)
View Source
var ErrImmatureChannel = errors.New("cannot remove immature channel, " +
	"still has ungraduated outputs")

ErrImmatureChannel signals a channel cannot be removed because not all of its outputs have graduated.

Functions

func DisableLog

func DisableLog()

DisableLog disables all library log output. Logging output is disabled by default until UseLogger is called.

func UseBreachLogger

func UseBreachLogger(logger btclog.Logger)

UseBreachLogger uses a specified Logger to output package logging info. This should be used in preference to SetLogWriter if the caller is also using btclog.

func UseLogger

func UseLogger(logger btclog.Logger)

UseLogger uses a specified Logger to output package logging info. This should be used in preference to SetLogWriter if the caller is also using btclog.

func UseNurseryLogger

func UseNurseryLogger(logger btclog.Logger)

UseNurseryLogger uses a specified Logger to output package logging info. This should be used in preference to SetLogWriter if the caller is also using btclog.

Types

type ArbChannel

type ArbChannel interface {
	// ForceCloseChan should force close the contract that this attendant
	// is watching over. We'll use this when we decide that we need to go
	// to chain. It should in addition tell the switch to remove the
	// corresponding link, such that we won't accept any new updates. The
	// returned summary contains all items needed to eventually resolve all
	// outputs on chain.
	ForceCloseChan() (*lnwallet.LocalForceCloseSummary, error)

	// NewAnchorResolutions returns the anchor resolutions for currently
	// valid commitment transactions.
	NewAnchorResolutions() (*lnwallet.AnchorResolutions, error)
}

ArbChannel is an abstraction that allows the channel arbitrator to interact with an open channel.

type ArbitratorLog

type ArbitratorLog interface {

	// CurrentState returns the current state of the ChannelArbitrator. It
	// takes an optional database transaction, which will be used if it is
	// non-nil, otherwise the lookup will be done in its own transaction.
	CurrentState(tx kvdb.RTx) (ArbitratorState, error)

	// CommitState persists, the current state of the chain attendant.
	CommitState(ArbitratorState) error

	// InsertUnresolvedContracts inserts a set of unresolved contracts into
	// the log. The log will then persistently store each contract until
	// they've been swapped out, or resolved. It takes a set of report which
	// should be written to disk if as well if it is non-nil.
	InsertUnresolvedContracts(reports []*channeldb.ResolverReport,
		resolvers ...ContractResolver) error

	// FetchUnresolvedContracts returns all unresolved contracts that have
	// been previously written to the log.
	FetchUnresolvedContracts() ([]ContractResolver, error)

	// SwapContract performs an atomic swap of the old contract for the new
	// contract. This method is used when after a contract has been fully
	// resolved, it produces another contract that needs to be resolved.
	SwapContract(old ContractResolver, new ContractResolver) error

	// ResolveContract marks a contract as fully resolved. Once a contract
	// has been fully resolved, it is deleted from persistent storage.
	ResolveContract(ContractResolver) error

	// LogContractResolutions stores a complete contract resolution for the
	// contract under watch. This method will be called once the
	// ChannelArbitrator either force closes a channel, or detects that the
	// remote party has broadcast their commitment on chain.
	LogContractResolutions(*ContractResolutions) error

	// FetchContractResolutions fetches the set of previously stored
	// contract resolutions from persistent storage.
	FetchContractResolutions() (*ContractResolutions, error)

	// InsertConfirmedCommitSet stores the known set of active HTLCs at the
	// time channel closure. We'll use this to reconstruct our set of chain
	// actions anew based on the confirmed and pending commitment state.
	InsertConfirmedCommitSet(c *CommitSet) error

	// FetchConfirmedCommitSet fetches the known confirmed active HTLC set
	// from the database. It takes an optional database transaction, which
	// will be used if it is non-nil, otherwise the lookup will be done in
	// its own transaction.
	FetchConfirmedCommitSet(tx kvdb.RTx) (*CommitSet, error)

	// FetchChainActions attempts to fetch the set of previously stored
	// chain actions. We'll use this upon restart to properly advance our
	// state machine forward.
	//
	// NOTE: This method only exists in order to be able to serve nodes had
	// channels in the process of closing before the CommitSet struct was
	// introduced.
	FetchChainActions() (ChainActionMap, error)

	// WipeHistory is to be called ONLY once *all* contracts have been
	// fully resolved, and the channel closure if finalized. This method
	// will delete all on-disk state within the persistent log.
	WipeHistory() error
}

ArbitratorLog is the primary source of persistent storage for the ChannelArbitrator. The log stores the current state of the ChannelArbitrator's internal state machine, any items that are required to properly make a state transition, and any unresolved contracts.

type ArbitratorState

type ArbitratorState uint8

ArbitratorState is an enum that details the current state of the ChannelArbitrator's state machine.

const (

	// StateDefault is the default state. In this state, no major actions
	// need to be executed.
	StateDefault ArbitratorState = 0

	// StateBroadcastCommit is a state that indicates that the attendant
	// has decided to broadcast the commitment transaction, but hasn't done
	// so yet.
	StateBroadcastCommit ArbitratorState = 1

	// StateCommitmentBroadcasted is a state that indicates that the
	// attendant has broadcasted the commitment transaction, and is now
	// waiting for it to confirm.
	StateCommitmentBroadcasted ArbitratorState = 6

	// StateContractClosed is a state that indicates the contract has
	// already been "closed", meaning the commitment is confirmed on chain.
	// At this point, we can now examine our active contracts, in order to
	// create the proper resolver for each one.
	StateContractClosed ArbitratorState = 2

	// StateWaitingFullResolution is a state that indicates that the
	// commitment transaction has been confirmed, and the attendant is now
	// waiting for all unresolved contracts to be fully resolved.
	StateWaitingFullResolution ArbitratorState = 3

	// StateFullyResolved is the final state of the attendant. In this
	// state, all related contracts have been resolved, and the attendant
	// can now be garbage collected.
	StateFullyResolved ArbitratorState = 4

	// StateError is the only error state of the resolver. If we enter this
	// state, then we cannot proceed with manual intervention as a state
	// transition failed.
	StateError ArbitratorState = 5
)

func (ArbitratorState) String

func (a ArbitratorState) String() string

String returns a human readable string describing the ArbitratorState.

type BreachArbiter

type BreachArbiter struct {
	sync.Mutex
	// contains filtered or unexported fields
}

BreachArbiter is a special subsystem which is responsible for watching and acting on the detection of any attempted uncooperative channel breaches by channel counterparties. This file essentially acts as deterrence code for those attempting to launch attacks against the daemon. In practice it's expected that the logic in this file never gets executed, but it is important to have it in place just in case we encounter cheating channel counterparties. TODO(roasbeef): closures in config for subsystem pointers to decouple?

func NewBreachArbiter

func NewBreachArbiter(cfg *BreachConfig) *BreachArbiter

NewBreachArbiter creates a new instance of a BreachArbiter initialized with its dependent objects.

func (*BreachArbiter) IsBreached

func (b *BreachArbiter) IsBreached(chanPoint *wire.OutPoint) (bool, error)

IsBreached queries the breach arbiter's retribution store to see if it is aware of any channel breaches for a particular channel point.

func (*BreachArbiter) Start

func (b *BreachArbiter) Start() error

Start is an idempotent method that officially starts the BreachArbiter along with all other goroutines it needs to perform its functions.

func (*BreachArbiter) Stop

func (b *BreachArbiter) Stop() error

Stop is an idempotent method that signals the BreachArbiter to execute a graceful shutdown. This function will block until all goroutines spawned by the BreachArbiter have gracefully exited.

func (*BreachArbiter) SubscribeBreachComplete

func (b *BreachArbiter) SubscribeBreachComplete(chanPoint *wire.OutPoint,
	c chan struct{}) (bool, error)

SubscribeBreachComplete is used by outside subsystems to be notified of a successful breach resolution.

type BreachCloseInfo

type BreachCloseInfo struct {
	*BreachResolution
	*lnwallet.AnchorResolution

	// CommitHash is the hash of the commitment transaction.
	CommitHash chainhash.Hash

	// CommitSet is the set of known valid commitments at the time the
	// breach occurred on-chain.
	CommitSet CommitSet

	// CloseSummary gives the recipient of the BreachCloseInfo information
	// to mark the channel closed in the database.
	CloseSummary channeldb.ChannelCloseSummary
}

BreachCloseInfo wraps the BreachResolution with a CommitSet for the latest, non-breached state, with the AnchorResolution for the breached state.

type BreachConfig

type BreachConfig struct {
	// CloseLink allows the breach arbiter to shutdown any channel links for
	// which it detects a breach, ensuring now further activity will
	// continue across the link. The method accepts link's channel point and
	// a close type to be included in the channel close summary.
	CloseLink func(*wire.OutPoint, ChannelCloseType)

	// DB provides access to the user's channels, allowing the breach
	// arbiter to determine the current state of a user's channels, and how
	// it should respond to channel closure.
	DB *channeldb.ChannelStateDB

	// Estimator is used by the breach arbiter to determine an appropriate
	// fee level when generating, signing, and broadcasting sweep
	// transactions.
	Estimator chainfee.Estimator

	// GenSweepScript generates the receiving scripts for swept outputs.
	GenSweepScript func() ([]byte, error)

	// Notifier provides a publish/subscribe interface for event driven
	// notifications regarding the confirmation of txids.
	Notifier chainntnfs.ChainNotifier

	// PublishTransaction facilitates the process of broadcasting a
	// transaction to the network.
	PublishTransaction func(*wire.MsgTx, string) error

	// ContractBreaches is a channel where the BreachArbiter will receive
	// notifications in the event of a contract breach being observed. A
	// ContractBreachEvent must be ACKed by the BreachArbiter, such that
	// the sending subsystem knows that the event is properly handed off.
	ContractBreaches <-chan *ContractBreachEvent

	// Signer is used by the breach arbiter to generate sweep transactions,
	// which move coins from previously open channels back to the user's
	// wallet.
	Signer input.Signer

	// Store is a persistent resource that maintains information regarding
	// breached channels. This is used in conjunction with DB to recover
	// from crashes, restarts, or other failures.
	Store RetributionStorer
}

BreachConfig bundles the required subsystems used by the breach arbiter. An instance of BreachConfig is passed to newBreachArbiter during instantiation.

type BreachResolution

type BreachResolution struct {
	FundingOutPoint wire.OutPoint
}

BreachResolution wraps the outpoint of the breached channel.

type ChainAction

type ChainAction uint8

ChainAction is an enum that encompasses all possible on-chain actions we'll take for a set of HTLC's.

func (ChainAction) String

func (c ChainAction) String() string

String returns a human readable string describing a chain action.

type ChainActionMap

type ChainActionMap map[ChainAction][]channeldb.HTLC

ChainActionMap is a map of a chain action, to the set of HTLC's that need to be acted upon for a given action type. The channel

func (ChainActionMap) Merge

func (c ChainActionMap) Merge(actions ChainActionMap)

Merge merges the passed chain actions with the target chain action map.

type ChainArbitrator

type ChainArbitrator struct {
	sync.Mutex
	// contains filtered or unexported fields
}

ChainArbitrator is a sub-system that oversees the on-chain resolution of all active, and channel that are in the "pending close" state. Within the contractcourt package, the ChainArbitrator manages a set of active ContractArbitrators. Each ContractArbitrators is responsible for watching the chain for any activity that affects the state of the channel, and also for monitoring each contract in order to determine if any on-chain activity is required. Outside sub-systems interact with the ChainArbitrator in order to forcibly exit a contract, update the set of live signals for each contract, and to receive reports on the state of contract resolution.

func NewChainArbitrator

func NewChainArbitrator(cfg ChainArbitratorConfig,
	db *channeldb.DB) *ChainArbitrator

NewChainArbitrator returns a new instance of the ChainArbitrator using the passed config struct, and backing persistent database.

func (*ChainArbitrator) ForceCloseContract

func (c *ChainArbitrator) ForceCloseContract(chanPoint wire.OutPoint) (*wire.MsgTx, error)

ForceCloseContract attempts to force close the channel infield by the passed channel point. A force close will immediately terminate the contract, causing it to enter the resolution phase. If the force close was successful, then the force close transaction itself will be returned.

TODO(roasbeef): just return the summary itself?

func (*ChainArbitrator) GetChannelArbitrator

func (c *ChainArbitrator) GetChannelArbitrator(chanPoint wire.OutPoint) (
	*ChannelArbitrator, error)

GetChannelArbitrator safely returns the channel arbitrator for a given channel outpoint.

func (*ChainArbitrator) NotifyContractUpdate

func (c *ChainArbitrator) NotifyContractUpdate(chanPoint wire.OutPoint,
	update *ContractUpdate) error

NotifyContractUpdate lets a channel arbitrator know that a new ContractUpdate is available. This calls the ChannelArbitrator's internal method NotifyContractUpdate which waits for a response on a done chan before returning. This method will return an error if the ChannelArbitrator is not in the activeChannels map. However, this only happens if the arbitrator is resolved and the related link would already be shut down.

func (*ChainArbitrator) ResolveContract

func (c *ChainArbitrator) ResolveContract(chanPoint wire.OutPoint) error

ResolveContract marks a contract as fully resolved within the database. This is only to be done once all contracts which were live on the channel before hitting the chain have been resolved.

func (*ChainArbitrator) Start

func (c *ChainArbitrator) Start() error

Start launches all goroutines that the ChainArbitrator needs to operate.

func (*ChainArbitrator) Stop

func (c *ChainArbitrator) Stop() error

Stop signals the ChainArbitrator to trigger a graceful shutdown. Any active channel arbitrators will be signalled to exit, and this method will block until they've all exited.

func (*ChainArbitrator) SubscribeChannelEvents

func (c *ChainArbitrator) SubscribeChannelEvents(
	chanPoint wire.OutPoint) (*ChainEventSubscription, error)

SubscribeChannelEvents returns a new active subscription for the set of possible on-chain events for a particular channel. The struct can be used by callers to be notified whenever an event that changes the state of the channel on-chain occurs.

func (*ChainArbitrator) UpdateContractSignals

func (c *ChainArbitrator) UpdateContractSignals(chanPoint wire.OutPoint,
	signals *ContractSignals) error

UpdateContractSignals sends a set of active, up to date contract signals to the ChannelArbitrator which is has been assigned to the channel infield by the passed channel point.

func (*ChainArbitrator) WatchNewChannel

func (c *ChainArbitrator) WatchNewChannel(newChan *channeldb.OpenChannel) error

WatchNewChannel sends the ChainArbitrator a message to create a ChannelArbitrator tasked with watching over a new channel. Once a new channel has finished its final funding flow, it should be registered with the ChainArbitrator so we can properly react to any on-chain events.

type ChainArbitratorConfig

type ChainArbitratorConfig struct {
	// ChainHash is the chain that this arbitrator is to operate within.
	ChainHash chainhash.Hash

	// IncomingBroadcastDelta is the delta that we'll use to decide when to
	// broadcast our commitment transaction if we have incoming htlcs. This
	// value should be set based on our current fee estimation of the
	// commitment transaction. We use this to determine when we should
	// broadcast instead of just the HTLC timeout, as we want to ensure
	// that the commitment transaction is already confirmed, by the time the
	// HTLC expires. Otherwise we may end up not settling the htlc on-chain
	// because the other party managed to time it out.
	IncomingBroadcastDelta uint32

	// OutgoingBroadcastDelta is the delta that we'll use to decide when to
	// broadcast our commitment transaction if there are active outgoing
	// htlcs. This value can be lower than the incoming broadcast delta.
	OutgoingBroadcastDelta uint32

	// NewSweepAddr is a function that returns a new address under control
	// by the wallet. We'll use this to sweep any no-delay outputs as a
	// result of unilateral channel closes.
	//
	// NOTE: This SHOULD return a p2wkh script.
	NewSweepAddr func() ([]byte, error)

	// PublishTx reliably broadcasts a transaction to the network. Once
	// this function exits without an error, then they transaction MUST
	// continually be rebroadcast if needed.
	PublishTx func(*wire.MsgTx, string) error

	// DeliverResolutionMsg is a function that will append an outgoing
	// message to the "out box" for a ChannelLink. This is used to cancel
	// backwards any HTLC's that are either dust, we're timing out, or
	// settling on-chain to the incoming link.
	DeliverResolutionMsg func(...ResolutionMsg) error

	// MarkLinkInactive is a function closure that the ChainArbitrator will
	// use to mark that active HTLC's shouldn't be attempted to be routed
	// over a particular channel. This function will be called in that a
	// ChannelArbitrator decides that it needs to go to chain in order to
	// resolve contracts.
	//
	// TODO(roasbeef): rename, routing based
	MarkLinkInactive func(wire.OutPoint) error

	// ContractBreach is a function closure that the ChainArbitrator will
	// use to notify the breachArbiter about a contract breach. It should
	// only return a non-nil error when the breachArbiter has preserved
	// the necessary breach info for this channel point. Once the breach
	// resolution is persisted in the channel arbitrator, it will be safe
	// to mark the channel closed.
	ContractBreach func(wire.OutPoint, *lnwallet.BreachRetribution) error

	// IsOurAddress is a function that returns true if the passed address
	// is known to the underlying wallet. Otherwise, false should be
	// returned.
	IsOurAddress func(btcutil.Address) bool

	// IncubateOutput sends either an incoming HTLC, an outgoing HTLC, or
	// both to the utxo nursery. Once this function returns, the nursery
	// should have safely persisted the outputs to disk, and should start
	// the process of incubation. This is used when a resolver wishes to
	// pass off the output to the nursery as we're only waiting on an
	// absolute/relative item block.
	IncubateOutputs func(wire.OutPoint, *lnwallet.OutgoingHtlcResolution,
		*lnwallet.IncomingHtlcResolution, uint32) error

	// PreimageDB is a global store of all known pre-images. We'll use this
	// to decide if we should broadcast a commitment transaction to claim
	// an HTLC on-chain.
	PreimageDB WitnessBeacon

	// Notifier is an instance of a chain notifier we'll use to watch for
	// certain on-chain events.
	Notifier chainntnfs.ChainNotifier

	// Mempool is the a mempool watcher that allows us to watch for events
	// happened in mempool.
	Mempool chainntnfs.MempoolWatcher

	// Signer is a signer backed by the active lnd node. This should be
	// capable of producing a signature as specified by a valid
	// SignDescriptor.
	Signer input.Signer

	// FeeEstimator will be used to return fee estimates.
	FeeEstimator chainfee.Estimator

	// ChainIO allows us to query the state of the current main chain.
	ChainIO lnwallet.BlockChainIO

	// DisableChannel disables a channel, resulting in it not being able to
	// forward payments.
	DisableChannel func(wire.OutPoint) error

	// Sweeper allows resolvers to sweep their final outputs.
	Sweeper UtxoSweeper

	// Registry is the invoice database that is used by resolvers to lookup
	// preimages and settle invoices.
	Registry Registry

	// NotifyClosedChannel is a function closure that the ChainArbitrator
	// will use to notify the ChannelNotifier about a newly closed channel.
	NotifyClosedChannel func(wire.OutPoint)

	// NotifyFullyResolvedChannel is a function closure that the
	// ChainArbitrator will use to notify the ChannelNotifier about a newly
	// resolved channel. The main difference to NotifyClosedChannel is that
	// in case of a local force close the NotifyClosedChannel is called when
	// the published commitment transaction confirms while
	// NotifyFullyResolvedChannel is only called when the channel is fully
	// resolved (which includes sweeping any time locked funds).
	NotifyFullyResolvedChannel func(point wire.OutPoint)

	// OnionProcessor is used to decode onion payloads for on-chain
	// resolution.
	OnionProcessor OnionProcessor

	// PaymentsExpirationGracePeriod indicates a time window we let the
	// other node to cancel an outgoing htlc that our node has initiated and
	// has timed out.
	PaymentsExpirationGracePeriod time.Duration

	// IsForwardedHTLC checks for a given htlc, identified by channel id and
	// htlcIndex, if it is a forwarded one.
	IsForwardedHTLC func(chanID lnwire.ShortChannelID, htlcIndex uint64) bool

	// Clock is the clock implementation that ChannelArbitrator uses.
	// It is useful for testing.
	Clock clock.Clock

	// SubscribeBreachComplete is used by the breachResolver to register a
	// subscription that notifies when the breach resolution process is
	// complete.
	SubscribeBreachComplete func(op *wire.OutPoint, c chan struct{}) (
		bool, error)

	// PutFinalHtlcOutcome stores the final outcome of an htlc in the
	// database.
	PutFinalHtlcOutcome func(chanId lnwire.ShortChannelID,
		htlcId uint64, settled bool) error

	// HtlcNotifier is an interface that htlc events are sent to.
	HtlcNotifier HtlcNotifier
}

ChainArbitratorConfig is a configuration struct that contains all the function closures and interface that required to arbitrate on-chain contracts for a particular chain.

type ChainEventSubscription

type ChainEventSubscription struct {
	// ChanPoint is that channel that chain events will be dispatched for.
	ChanPoint wire.OutPoint

	// RemoteUnilateralClosure is a channel that will be sent upon in the
	// event that the remote party's commitment transaction is confirmed.
	RemoteUnilateralClosure chan *RemoteUnilateralCloseInfo

	// LocalUnilateralClosure is a channel that will be sent upon in the
	// event that our commitment transaction is confirmed.
	LocalUnilateralClosure chan *LocalUnilateralCloseInfo

	// CooperativeClosure is a signal that will be sent upon once a
	// cooperative channel closure has been detected confirmed.
	CooperativeClosure chan *CooperativeCloseInfo

	// ContractBreach is a channel that will be sent upon if we detect a
	// contract breach. The struct sent across the channel contains all the
	// material required to bring the cheating channel peer to justice.
	ContractBreach chan *BreachCloseInfo

	// Cancel cancels the subscription to the event stream for a particular
	// channel. This method should be called once the caller no longer needs to
	// be notified of any on-chain events for a particular channel.
	Cancel func()
}

ChainEventSubscription is a struct that houses a subscription to be notified for any on-chain events related to a channel. There are three types of possible on-chain events: a cooperative channel closure, a unilateral channel closure, and a channel breach. The fourth type: a force close is locally initiated, so we don't provide any event stream for said event.

type ChannelArbitrator

type ChannelArbitrator struct {
	// contains filtered or unexported fields
}

ChannelArbitrator is the on-chain arbitrator for a particular channel. The struct will keep in sync with the current set of HTLCs on the commitment transaction. The job of the attendant is to go on-chain to either settle or cancel an HTLC as necessary iff: an HTLC times out, or we known the pre-image to an HTLC, but it wasn't settled by the link off-chain. The ChannelArbitrator will factor in an expected confirmation delta when broadcasting to ensure that we avoid any possibility of race conditions, and sweep the output(s) without contest.

func NewChannelArbitrator

func NewChannelArbitrator(cfg ChannelArbitratorConfig,
	htlcSets map[HtlcSetKey]htlcSet, log ArbitratorLog) *ChannelArbitrator

NewChannelArbitrator returns a new instance of a ChannelArbitrator backed by the passed config struct.

func (*ChannelArbitrator) Report

func (c *ChannelArbitrator) Report() []*ContractReport

Report returns htlc reports for the active resolvers.

func (*ChannelArbitrator) Start

func (c *ChannelArbitrator) Start(state *chanArbStartState) error

Start starts all the goroutines that the ChannelArbitrator needs to operate. If takes a start state, which will be looked up on disk if it is not provided.

func (*ChannelArbitrator) Stop

func (c *ChannelArbitrator) Stop() error

Stop signals the ChannelArbitrator for a graceful shutdown.

func (*ChannelArbitrator) UpdateContractSignals

func (c *ChannelArbitrator) UpdateContractSignals(newSignals *ContractSignals)

UpdateContractSignals updates the set of signals the ChannelArbitrator needs to receive from a channel in real-time in order to keep in sync with the latest state of the contract.

type ChannelArbitratorConfig

type ChannelArbitratorConfig struct {
	// ChanPoint is the channel point that uniquely identifies this
	// channel.
	ChanPoint wire.OutPoint

	// Channel is the full channel data structure. For legacy channels, this
	// field may not always be set after a restart.
	Channel ArbChannel

	// ShortChanID describes the exact location of the channel within the
	// chain. We'll use this to address any messages that we need to send
	// to the switch during contract resolution.
	ShortChanID lnwire.ShortChannelID

	// ChainEvents is an active subscription to the chain watcher for this
	// channel to be notified of any on-chain activity related to this
	// channel.
	ChainEvents *ChainEventSubscription

	// MarkCommitmentBroadcasted should mark the channel as the commitment
	// being broadcast, and we are waiting for the commitment to confirm.
	MarkCommitmentBroadcasted func(*wire.MsgTx, bool) error

	// MarkChannelClosed marks the channel closed in the database, with the
	// passed close summary. After this method successfully returns we can
	// no longer expect to receive chain events for this channel, and must
	// be able to recover from a failure without getting the close event
	// again. It takes an optional channel status which will update the
	// channel status in the record that we keep of historical channels.
	MarkChannelClosed func(*channeldb.ChannelCloseSummary,
		...channeldb.ChannelStatus) error

	// IsPendingClose is a boolean indicating whether the channel is marked
	// as pending close in the database.
	IsPendingClose bool

	// ClosingHeight is the height at which the channel was closed. Note
	// that this value is only valid if IsPendingClose is true.
	ClosingHeight uint32

	// CloseType is the type of the close event in case IsPendingClose is
	// true. Otherwise this value is unset.
	CloseType channeldb.ClosureType

	// MarkChannelResolved is a function closure that serves to mark a
	// channel as "fully resolved". A channel itself can be considered
	// fully resolved once all active contracts have individually been
	// fully resolved.
	//
	// TODO(roasbeef): need RPC's to combine for pendingchannels RPC
	MarkChannelResolved func() error

	// PutResolverReport records a resolver report for the channel. If the
	// transaction provided is nil, the function should write the report
	// in a new transaction.
	PutResolverReport func(tx kvdb.RwTx,
		report *channeldb.ResolverReport) error

	// FetchHistoricalChannel retrieves the historical state of a channel.
	// This is mostly used to supplement the ContractResolvers with
	// additional information required for proper contract resolution.
	FetchHistoricalChannel func() (*channeldb.OpenChannel, error)

	ChainArbitratorConfig
}

ChannelArbitratorConfig contains all the functionality that the ChannelArbitrator needs in order to properly arbitrate any contract dispute on chain.

type ChannelCloseType

type ChannelCloseType uint8

ChannelCloseType is an enum which signals the type of channel closure the peer should execute.

const (
	// CloseRegular indicates a regular cooperative channel closure
	// should be attempted.
	CloseRegular ChannelCloseType = iota

	// CloseBreach indicates that a channel breach has been detected, and
	// the link should immediately be marked as unavailable.
	CloseBreach
)

type CommitSet

type CommitSet struct {
	// ConfCommitKey if non-nil, identifies the commitment that was
	// confirmed in the chain.
	ConfCommitKey *HtlcSetKey

	// HtlcSets stores the set of all known active HTLC for each active
	// commitment at the time of channel closure.
	HtlcSets map[HtlcSetKey][]channeldb.HTLC
}

CommitSet is a collection of the set of known valid commitments at a given instant. If ConfCommitKey is set, then the commitment identified by the HtlcSetKey has hit the chain. This struct will be used to examine all live HTLCs to determine if any additional actions need to be made based on the remote party's commitments.

func (*CommitSet) IsEmpty

func (c *CommitSet) IsEmpty() bool

IsEmpty returns true if there are no HTLCs at all within all commitments that are a part of this commitment diff.

type ContractBreachEvent

type ContractBreachEvent struct {
	// ChanPoint is the channel point of the breached channel.
	ChanPoint wire.OutPoint

	// ProcessACK is an closure that should be called with a nil error iff
	// the breach retribution info is safely stored in the retribution
	// store. In case storing the information to the store fails, a non-nil
	// error should be used. When this closure returns, it means that the
	// contract court has marked the channel pending close in the DB, and
	// it is safe for the BreachArbiter to carry on its duty.
	ProcessACK func(error)

	// BreachRetribution is the information needed to act on this contract
	// breach.
	BreachRetribution *lnwallet.BreachRetribution
}

ContractBreachEvent is an event the BreachArbiter will receive in case a contract breach is observed on-chain. It contains the necessary information to handle the breach, and a ProcessACK closure we will use to ACK the event when we have safely stored all the necessary information.

type ContractMaturityReport

type ContractMaturityReport struct {
	// limboBalance is the total number of frozen coins within this
	// contract.
	LimboBalance btcutil.Amount

	// recoveredBalance is the total value that has been successfully swept
	// back to the user's wallet.
	RecoveredBalance btcutil.Amount

	// htlcs records a maturity report for each htlc output in this channel.
	Htlcs []HtlcMaturityReport
}

ContractMaturityReport is a report that details the maturity progress of a particular force closed contract.

func (*ContractMaturityReport) AddLimboDirectHtlc

func (c *ContractMaturityReport) AddLimboDirectHtlc(kid *kidOutput)

AddLimboDirectHtlc adds a direct HTLC on the commitment transaction of the remote party to the maturity report. This a CLTV time-locked output that has or hasn't expired yet.

func (*ContractMaturityReport) AddLimboStage1SuccessHtlc

func (c *ContractMaturityReport) AddLimboStage1SuccessHtlc(kid *kidOutput)

AddLimboStage1SuccessHtlcHtlc adds an htlc crib output to the maturity report's set of HTLC's. We'll use this to report any incoming HTLC sweeps where the second level transaction hasn't yet confirmed.

func (*ContractMaturityReport) AddLimboStage1TimeoutHtlc

func (c *ContractMaturityReport) AddLimboStage1TimeoutHtlc(baby *babyOutput)

AddLimboStage1TimeoutHtlc adds an htlc crib output to the maturity report's htlcs, and contributes its amount to the limbo balance.

func (*ContractMaturityReport) AddLimboStage2Htlc

func (c *ContractMaturityReport) AddLimboStage2Htlc(kid *kidOutput)

AddLimboStage2Htlc adds an htlc kindergarten output to the maturity report's htlcs, and contributes its amount to the limbo balance.

func (*ContractMaturityReport) AddRecoveredHtlc

func (c *ContractMaturityReport) AddRecoveredHtlc(kid *kidOutput)

AddRecoveredHtlc adds a graduate output to the maturity report's htlcs, and contributes its amount to the recovered balance.

type ContractReport

type ContractReport struct {
	// Outpoint is the final output that will be swept back to the wallet.
	Outpoint wire.OutPoint

	// Type indicates the type of the reported output.
	Type ReportOutputType

	// Amount is the final value that will be swept in back to the wallet.
	Amount btcutil.Amount

	// MaturityHeight is the absolute block height that this output will
	// mature at.
	MaturityHeight uint32

	// Stage indicates whether the htlc is in the CLTV-timeout stage (1) or
	// the CSV-delay stage (2). A stage 1 htlc's maturity height will be set
	// to its expiry height, while a stage 2 htlc's maturity height will be
	// set to its confirmation height plus the maturity requirement.
	Stage uint32

	// LimboBalance is the total number of frozen coins within this
	// contract.
	LimboBalance btcutil.Amount

	// RecoveredBalance is the total value that has been successfully swept
	// back to the user's wallet.
	RecoveredBalance btcutil.Amount
}

ContractReport provides a summary of a commitment tx output.

type ContractResolutions

type ContractResolutions struct {
	// CommitHash is the txid of the commitment transaction.
	CommitHash chainhash.Hash

	// CommitResolution contains all data required to fully resolve a
	// commitment output.
	CommitResolution *lnwallet.CommitOutputResolution

	// HtlcResolutions contains all data required to fully resolve any
	// incoming+outgoing HTLC's present within the commitment transaction.
	HtlcResolutions lnwallet.HtlcResolutions

	// AnchorResolution contains the data required to sweep the anchor
	// output. If the channel type doesn't include anchors, the value of
	// this field will be nil.
	AnchorResolution *lnwallet.AnchorResolution

	// BreachResolution contains the data required to manage the lifecycle
	// of a breach in the ChannelArbitrator.
	BreachResolution *BreachResolution
}

ContractResolutions is a wrapper struct around the two forms of resolutions we may need to carry out once a contract is closing: resolving the commitment output, and resolving any incoming+outgoing HTLC's still present in the commitment.

func (*ContractResolutions) IsEmpty

func (c *ContractResolutions) IsEmpty() bool

IsEmpty returns true if the set of resolutions is "empty". A resolution is empty if: our commitment output has been trimmed, we don't have any incoming or outgoing HTLC's active, there is no anchor output to sweep, or there are no breached outputs to resolve.

type ContractResolver

type ContractResolver interface {
	// ResolverKey returns an identifier which should be globally unique
	// for this particular resolver within the chain the original contract
	// resides within.
	ResolverKey() []byte

	// Resolve instructs the contract resolver to resolve the output
	// on-chain. Once the output has been *fully* resolved, the function
	// should return immediately with a nil ContractResolver value for the
	// first return value.  In the case that the contract requires further
	// resolution, then another resolve is returned.
	//
	// NOTE: This function MUST be run as a goroutine.
	Resolve() (ContractResolver, error)

	// SupplementState allows the user of a ContractResolver to supplement
	// it with state required for the proper resolution of a contract.
	SupplementState(*channeldb.OpenChannel)

	// IsResolved returns true if the stored state in the resolve is fully
	// resolved. In this case the target output can be forgotten.
	IsResolved() bool

	// Encode writes an encoded version of the ContractResolver into the
	// passed Writer.
	Encode(w io.Writer) error

	// Stop signals the resolver to cancel any current resolution
	// processes, and suspend.
	Stop()
}

ContractResolver is an interface which packages a state machine which is able to carry out the necessary steps required to fully resolve a Bitcoin contract on-chain. Resolvers are fully encodable to ensure callers are able to persist them properly. A resolver may produce another resolver in the case that claiming an HTLC is a multi-stage process. In this case, we may partially resolve the contract, then persist, and set up for an additional resolution.

type ContractSignals

type ContractSignals struct {
	// ShortChanID is the up to date short channel ID for a contract. This
	// can change either if when the contract was added it didn't yet have
	// a stable identifier, or in the case of a reorg.
	ShortChanID lnwire.ShortChannelID
}

ContractSignals is used by outside subsystems to notify a channel arbitrator of its ShortChannelID.

type ContractUpdate

type ContractUpdate struct {
	// HtlcKey identifies which commitment the HTLCs below are present on.
	HtlcKey HtlcSetKey

	// Htlcs are the of active HTLCs on the commitment identified by the
	// above HtlcKey.
	Htlcs []channeldb.HTLC
}

ContractUpdate is a message packages the latest set of active HTLCs on a commitment, and also identifies which commitment received a new set of HTLCs.

type CooperativeCloseInfo

type CooperativeCloseInfo struct {
	*channeldb.ChannelCloseSummary
}

CooperativeCloseInfo encapsulates all the information we need to act on a cooperative close that gets confirmed.

type HtlcMaturityReport

type HtlcMaturityReport struct {
	// Outpoint is the final output that will be swept back to the wallet.
	Outpoint wire.OutPoint

	// Amount is the final value that will be swept in back to the wallet.
	Amount btcutil.Amount

	// MaturityHeight is the absolute block height that this output will
	// mature at.
	MaturityHeight uint32

	// Stage indicates whether the htlc is in the CLTV-timeout stage (1) or
	// the CSV-delay stage (2). A stage 1 htlc's maturity height will be set
	// to its expiry height, while a stage 2 htlc's maturity height will be
	// set to its confirmation height plus the maturity requirement.
	Stage uint32
}

HtlcMaturityReport provides a summary of a single htlc output, and is embedded as party of the overarching ContractMaturityReport.

type HtlcNotifier

type HtlcNotifier interface {
	// NotifyFinalHtlcEvent notifies the HtlcNotifier that the final outcome
	// for an htlc has been determined.
	NotifyFinalHtlcEvent(key models.CircuitKey,
		info channeldb.FinalHtlcInfo)
}

HtlcNotifier defines the notification functions that contract court requires.

type HtlcSetKey

type HtlcSetKey struct {
	// IsRemote denotes if the HTLCs are on the remote commitment
	// transaction.
	IsRemote bool

	// IsPending denotes if the commitment transaction that HTLCS are on
	// are pending (the higher of two unrevoked commitments).
	IsPending bool
}

HtlcSetKey is a two-tuple that uniquely identifies a set of HTLCs on a commitment transaction.

func (HtlcSetKey) String

func (h HtlcSetKey) String() string

String returns a human readable string describing the target HtlcSetKey.

type LocalUnilateralCloseInfo

type LocalUnilateralCloseInfo struct {
	*chainntnfs.SpendDetail
	*lnwallet.LocalForceCloseSummary
	*channeldb.ChannelCloseSummary

	// CommitSet is the set of known valid commitments at the time the
	// remote party's commitment hit the chain.
	CommitSet CommitSet
}

LocalUnilateralCloseInfo encapsulates all the information we need to act on a local force close that gets confirmed.

type NurseryConfig

type NurseryConfig struct {
	// ChainIO is used by the utxo nursery to determine the current block
	// height, which drives the incubation of the nursery's outputs.
	ChainIO lnwallet.BlockChainIO

	// ConfDepth is the number of blocks the nursery store waits before
	// determining outputs in the chain as confirmed.
	ConfDepth uint32

	// FetchClosedChannels provides access to a user's channels, such that
	// they can be marked fully closed after incubation has concluded.
	FetchClosedChannels func(pendingOnly bool) (
		[]*channeldb.ChannelCloseSummary, error)

	// FetchClosedChannel provides access to the close summary to extract a
	// height hint from.
	FetchClosedChannel func(chanID *wire.OutPoint) (
		*channeldb.ChannelCloseSummary, error)

	// Notifier provides the utxo nursery the ability to subscribe to
	// transaction confirmation events, which advance outputs through their
	// persistence state transitions.
	Notifier chainntnfs.ChainNotifier

	// PublishTransaction facilitates the process of broadcasting a signed
	// transaction to the appropriate network.
	PublishTransaction func(*wire.MsgTx, string) error

	// Store provides access to and modification of the persistent state
	// maintained about the utxo nursery's incubating outputs.
	Store NurseryStorer

	// Sweep sweeps an input back to the wallet.
	SweepInput func(input.Input, sweep.Params) (chan sweep.Result, error)
}

NurseryConfig abstracts the required subsystems used by the utxo nursery. An instance of NurseryConfig is passed to newUtxoNursery during instantiation.

type NurseryStore

type NurseryStore struct {
	// contains filtered or unexported fields
}

NurseryStore is a concrete instantiation of a NurseryStore that is backed by a channeldb.DB instance.

func NewNurseryStore

func NewNurseryStore(chainHash *chainhash.Hash,
	db *channeldb.DB) (*NurseryStore, error)

NewNurseryStore accepts a chain hash and a channeldb.DB instance, returning an instance of NurseryStore who's database is properly segmented for the given chain.

func (*NurseryStore) CribToKinder

func (ns *NurseryStore) CribToKinder(bby *babyOutput) error

CribToKinder atomically moves a babyOutput in the crib bucket to the kindergarten bucket. The now mature kidOutput contained in the babyOutput will be stored as it waits out the kidOutput's CSV delay.

func (*NurseryStore) FetchClass

func (ns *NurseryStore) FetchClass(
	height uint32) ([]kidOutput, []babyOutput, error)

FetchClass returns a list of babyOutputs in the crib bucket whose CLTV delay expires at the provided block height. FetchClass returns a list of the kindergarten and crib outputs whose timeouts are expiring

func (*NurseryStore) FetchPreschools

func (ns *NurseryStore) FetchPreschools() ([]kidOutput, error)

FetchPreschools returns a list of all outputs currently stored in the preschool bucket.

func (*NurseryStore) ForChanOutputs

func (ns *NurseryStore) ForChanOutputs(chanPoint *wire.OutPoint,
	callback func([]byte, []byte) error, reset func()) error

ForChanOutputs iterates over all outputs being incubated for a particular channel point. This method accepts a callback that allows the caller to process each key-value pair. The key will be a prefixed outpoint, and the value will be the serialized bytes for an output, whose type should be inferred from the key's prefix. NOTE: The callback should not modify the provided byte slices and is preferably non-blocking.

func (*NurseryStore) GraduateKinder

func (ns *NurseryStore) GraduateKinder(height uint32, kid *kidOutput) error

GraduateKinder atomically moves an output at the provided height into the graduated status. This involves removing the kindergarten entries from both the height and channel indexes. The height bucket will be opportunistically pruned from the height index as outputs are removed.

func (*NurseryStore) HeightsBelowOrEqual

func (ns *NurseryStore) HeightsBelowOrEqual(height uint32) ([]uint32, error)

HeightsBelowOrEqual returns a slice of all non-empty heights in the height index at or below the provided upper bound.

func (*NurseryStore) Incubate

func (ns *NurseryStore) Incubate(kids []kidOutput, babies []babyOutput) error

Incubate persists the beginning of the incubation process for the CSV-delayed outputs (commitment and incoming HTLC's), commitment output and a list of outgoing two-stage htlc outputs.

func (*NurseryStore) IsMatureChannel

func (ns *NurseryStore) IsMatureChannel(chanPoint *wire.OutPoint) (bool, error)

IsMatureChannel determines the whether or not all of the outputs in a particular channel bucket have been marked as graduated.

func (*NurseryStore) ListChannels

func (ns *NurseryStore) ListChannels() ([]wire.OutPoint, error)

ListChannels returns all channels the nursery is currently tracking.

func (*NurseryStore) PreschoolToKinder

func (ns *NurseryStore) PreschoolToKinder(kid *kidOutput,
	lastGradHeight uint32) error

PreschoolToKinder atomically moves a kidOutput from the preschool bucket to the kindergarten bucket. This transition should be executed after receiving confirmation of the preschool output's commitment transaction.

func (*NurseryStore) RemoveChannel

func (ns *NurseryStore) RemoveChannel(chanPoint *wire.OutPoint) error

RemoveChannel channel erases all entries from the channel bucket for the provided channel point. NOTE: The channel's entries in the height index are assumed to be removed.

type NurseryStorer

type NurseryStorer interface {
	// Incubate registers a set of CSV delayed outputs (incoming HTLC's on
	// our commitment transaction, or a commitment output), and a slice of
	// outgoing htlc outputs to be swept back into the user's wallet. The
	// event is persisted to disk, such that the nursery can resume the
	// incubation process after a potential crash.
	Incubate([]kidOutput, []babyOutput) error

	// CribToKinder atomically moves a babyOutput in the crib bucket to the
	// kindergarten bucket. Baby outputs are outgoing HTLC's which require
	// us to go to the second-layer to claim. The now mature kidOutput
	// contained in the babyOutput will be stored as it waits out the
	// kidOutput's CSV delay.
	CribToKinder(*babyOutput) error

	// PreschoolToKinder atomically moves a kidOutput from the preschool
	// bucket to the kindergarten bucket. This transition should be executed
	// after receiving confirmation of the preschool output. Incoming HTLC's
	// we need to go to the second-layer to claim, and also our commitment
	// outputs fall into this class.
	//
	// An additional parameter specifies the last graduated height. This is
	// used in case of late registration. It schedules the output for sweep
	// at the next epoch even though it has already expired earlier.
	PreschoolToKinder(kid *kidOutput, lastGradHeight uint32) error

	// GraduateKinder atomically moves an output at the provided height into
	// the graduated status. This involves removing the kindergarten entries
	// from both the height and channel indexes. The height bucket will be
	// opportunistically pruned from the height index as outputs are
	// removed.
	GraduateKinder(height uint32, output *kidOutput) error

	// FetchPreschools returns a list of all outputs currently stored in
	// the preschool bucket.
	FetchPreschools() ([]kidOutput, error)

	// FetchClass returns a list of kindergarten and crib outputs whose
	// timelocks expire at the given height.
	FetchClass(height uint32) ([]kidOutput, []babyOutput, error)

	// HeightsBelowOrEqual returns the lowest non-empty heights in the
	// height index, that exist at or below the provided upper bound.
	HeightsBelowOrEqual(height uint32) ([]uint32, error)

	// ForChanOutputs iterates over all outputs being incubated for a
	// particular channel point. This method accepts a callback that allows
	// the caller to process each key-value pair. The key will be a prefixed
	// outpoint, and the value will be the serialized bytes for an output,
	// whose type should be inferred from the key's prefix.
	ForChanOutputs(*wire.OutPoint, func([]byte, []byte) error, func()) error

	// ListChannels returns all channels the nursery is currently tracking.
	ListChannels() ([]wire.OutPoint, error)

	// IsMatureChannel determines the whether or not all of the outputs in a
	// particular channel bucket have been marked as graduated.
	IsMatureChannel(*wire.OutPoint) (bool, error)

	// RemoveChannel channel erases all entries from the channel bucket for
	// the provided channel point, this method should only be called if
	// IsMatureChannel indicates the channel is ready for removal.
	RemoveChannel(*wire.OutPoint) error
}

NurseryStore abstracts the persistent storage layer for the utxo nursery. Concretely, it stores commitment and htlc outputs until any time-bounded constraints have fully matured. The store exposes methods for enumerating its contents, and persisting state transitions detected by the utxo nursery.

type OnionProcessor

type OnionProcessor interface {
	// ReconstructHopIterator attempts to decode a valid sphinx packet from
	// the passed io.Reader instance.
	ReconstructHopIterator(r io.Reader, rHash []byte) (hop.Iterator, error)
}

OnionProcessor is an interface used to decode onion blobs.

type Registry

type Registry interface {
	// LookupInvoice attempts to look up an invoice according to its 32
	// byte payment hash.
	LookupInvoice(lntypes.Hash) (invoices.Invoice, error)

	// NotifyExitHopHtlc attempts to mark an invoice as settled. If the
	// invoice is a debug invoice, then this method is a noop as debug
	// invoices are never fully settled. The return value describes how the
	// htlc should be resolved. If the htlc cannot be resolved immediately,
	// the resolution is sent on the passed in hodlChan later.
	NotifyExitHopHtlc(payHash lntypes.Hash, paidAmount lnwire.MilliSatoshi,
		expiry uint32, currentHeight int32,
		circuitKey models.CircuitKey, hodlChan chan<- interface{},
		payload invoices.Payload) (invoices.HtlcResolution, error)

	// HodlUnsubscribeAll unsubscribes from all htlc resolutions.
	HodlUnsubscribeAll(subscriber chan<- interface{})
}

Registry is an interface which represents the invoice registry.

type RemoteUnilateralCloseInfo

type RemoteUnilateralCloseInfo struct {
	*lnwallet.UnilateralCloseSummary

	// CommitSet is the set of known valid commitments at the time the
	// remote party's commitment hit the chain.
	CommitSet CommitSet
}

RemoteUnilateralCloseInfo wraps the normal UnilateralCloseSummary to couple the CommitSet at the time of channel closure.

type ReportOutputType

type ReportOutputType uint8

ReportOutputType describes the type of output that is being reported on.

const (
	// ReportOutputIncomingHtlc is an incoming hash time locked contract on
	// the commitment tx.
	ReportOutputIncomingHtlc ReportOutputType = iota

	// ReportOutputOutgoingHtlc is an outgoing hash time locked contract on
	// the commitment tx.
	ReportOutputOutgoingHtlc

	// ReportOutputUnencumbered is an uncontested output on the commitment
	// transaction paying to us directly.
	ReportOutputUnencumbered

	// ReportOutputAnchor is an anchor output on the commitment tx.
	ReportOutputAnchor
)

type ResolutionMsg

type ResolutionMsg struct {
	// SourceChan identifies the channel that this message is being sent
	// from. This is the channel's short channel ID.
	SourceChan lnwire.ShortChannelID

	// HtlcIndex is the index of the contract within the original
	// commitment trace.
	HtlcIndex uint64

	// Failure will be non-nil if the incoming contract should be canceled
	// all together. This can happen if the outgoing contract was dust, if
	// if the outgoing HTLC timed out.
	Failure lnwire.FailureMessage

	// PreImage will be non-nil if the incoming contract can successfully
	// be redeemed. This can happen if we learn of the preimage from the
	// outgoing HTLC on-chain.
	PreImage *[32]byte
}

ResolutionMsg is a message sent by resolvers to outside sub-systems once an outgoing contract has been fully resolved. For multi-hop contracts, if we resolve the outgoing contract, we'll also need to ensure that the incoming contract is resolved as well. We package the items required to resolve the incoming contracts within this message.

type ResolverConfig

type ResolverConfig struct {
	// ChannelArbitratorConfig contains all the interfaces and closures
	// required for the resolver to interact with outside sub-systems.
	ChannelArbitratorConfig

	// Checkpoint allows a resolver to check point its state. This function
	// should write the state of the resolver to persistent storage, and
	// return a non-nil error upon success. It takes a resolver report,
	// which contains information about the outcome and should be written
	// to disk if non-nil.
	Checkpoint func(ContractResolver, ...*channeldb.ResolverReport) error
}

ResolverConfig contains the externally supplied configuration items that are required by a ContractResolver implementation.

type RetributionStore

type RetributionStore struct {
	// contains filtered or unexported fields
}

RetributionStore handles persistence of retribution states to disk and is backed by a boltdb bucket. The primary responsibility of the retribution store is to ensure that we can recover from a restart in the middle of a breached contract retribution.

func NewRetributionStore

func NewRetributionStore(db kvdb.Backend) *RetributionStore

NewRetributionStore creates a new instance of a RetributionStore.

func (*RetributionStore) Add

func (rs *RetributionStore) Add(ret *retributionInfo) error

Add adds a retribution state to the RetributionStore, which is then persisted to disk.

func (*RetributionStore) ForAll

func (rs *RetributionStore) ForAll(cb func(*retributionInfo) error,
	reset func()) error

ForAll iterates through all stored retributions and executes the passed callback function on each retribution.

func (*RetributionStore) IsBreached

func (rs *RetributionStore) IsBreached(chanPoint *wire.OutPoint) (bool, error)

IsBreached queries the retribution store to discern if this channel was previously breached. This is used when connecting to a peer to determine if it is safe to add a link to the htlcswitch, as we should never add a channel that has already been breached.

func (*RetributionStore) Remove

func (rs *RetributionStore) Remove(chanPoint *wire.OutPoint) error

Remove removes a retribution state and finalized justice transaction by channel point from the retribution store.

type RetributionStorer

type RetributionStorer interface {
	// Add persists the retributionInfo to disk, using the information's
	// chanPoint as the key. This method should overwrite any existing
	// entries found under the same key, and an error should be raised if
	// the addition fails.
	Add(retInfo *retributionInfo) error

	// IsBreached queries the retribution store to see if the breach arbiter
	// is aware of any breaches for the provided channel point.
	IsBreached(chanPoint *wire.OutPoint) (bool, error)

	// Remove deletes the retributionInfo from disk, if any exists, under
	// the given key. An error should be re raised if the removal fails.
	Remove(key *wire.OutPoint) error

	// ForAll iterates over the existing on-disk contents and applies a
	// chosen, read-only callback to each. This method should ensure that it
	// immediately propagate any errors generated by the callback.
	ForAll(cb func(*retributionInfo) error, reset func()) error
}

RetributionStorer provides an interface for managing a persistent map from wire.OutPoint -> retributionInfo. Upon learning of a breach, a BreachArbiter should record the retributionInfo for the breached channel, which serves a checkpoint in the event that retribution needs to be resumed after failure. A RetributionStore provides an interface for managing the persisted set, as well as mapping user defined functions over the entire on-disk contents.

Calls to RetributionStore may occur concurrently. A concrete instance of RetributionStore should use appropriate synchronization primitives, or be otherwise safe for concurrent access.

type UtxoNursery

type UtxoNursery struct {
	// contains filtered or unexported fields
}

UtxoNursery is a system dedicated to incubating time-locked outputs created by the broadcast of a commitment transaction either by us, or the remote peer. The nursery accepts outputs and "incubates" them until they've reached maturity, then sweep the outputs into the source wallet. An output is considered mature after the relative time-lock within the pkScript has passed. As outputs reach their maturity age, they're swept in batches into the source wallet, returning the outputs so they can be used within future channels, or regular Bitcoin transactions.

func NewUtxoNursery

func NewUtxoNursery(cfg *NurseryConfig) *UtxoNursery

NewUtxoNursery creates a new instance of the UtxoNursery from a ChainNotifier and LightningWallet instance.

func (*UtxoNursery) IncubateOutputs

func (u *UtxoNursery) IncubateOutputs(chanPoint wire.OutPoint,
	outgoingHtlcs []lnwallet.OutgoingHtlcResolution,
	incomingHtlcs []lnwallet.IncomingHtlcResolution,
	broadcastHeight uint32) error

IncubateOutputs sends a request to the UtxoNursery to incubate a set of outputs from an existing commitment transaction. Outputs need to incubate if they're CLTV absolute time locked, or if they're CSV relative time locked. Once all outputs reach maturity, they'll be swept back into the wallet.

func (*UtxoNursery) NurseryReport

func (u *UtxoNursery) NurseryReport(
	chanPoint *wire.OutPoint) (*ContractMaturityReport, error)

NurseryReport attempts to return a nursery report stored for the target outpoint. A nursery report details the maturity/sweeping progress for a contract that was previously force closed. If a report entry for the target chanPoint is unable to be constructed, then an error will be returned.

func (*UtxoNursery) RemoveChannel

func (u *UtxoNursery) RemoveChannel(op *wire.OutPoint) error

RemoveChannel channel erases all entries from the channel bucket for the provided channel point.

func (*UtxoNursery) Start

func (u *UtxoNursery) Start() error

Start launches all goroutines the UtxoNursery needs to properly carry out its duties.

func (*UtxoNursery) Stop

func (u *UtxoNursery) Stop() error

Stop gracefully shuts down any lingering goroutines launched during normal operation of the UtxoNursery.

type UtxoSweeper

type UtxoSweeper interface {
	// SweepInput sweeps inputs back into the wallet.
	SweepInput(input input.Input, params sweep.Params) (chan sweep.Result,
		error)

	// CreateSweepTx accepts a list of inputs and signs and generates a txn
	// that spends from them. This method also makes an accurate fee
	// estimate before generating the required witnesses.
	CreateSweepTx(inputs []input.Input, feePref sweep.FeePreference,
		currentBlockHeight uint32) (*wire.MsgTx, error)

	// RelayFeePerKW returns the minimum fee rate required for transactions
	// to be relayed.
	RelayFeePerKW() chainfee.SatPerKWeight

	// UpdateParams allows updating the sweep parameters of a pending input
	// in the UtxoSweeper. This function can be used to provide an updated
	// fee preference that will be used for a new sweep transaction of the
	// input that will act as a replacement transaction (RBF) of the
	// original sweeping transaction, if any.
	UpdateParams(input wire.OutPoint, params sweep.ParamsUpdate) (
		chan sweep.Result, error)
}

UtxoSweeper defines the sweep functions that contract court requires.

type WitnessBeacon

type WitnessBeacon interface {
	// SubscribeUpdates returns a channel that will be sent upon *each* time
	// a new preimage is discovered.
	SubscribeUpdates(chanID lnwire.ShortChannelID, htlc *channeldb.HTLC,
		payload *hop.Payload,
		nextHopOnionBlob []byte) (*WitnessSubscription, error)

	// LookupPreImage attempts to lookup a preimage in the global cache.
	// True is returned for the second argument if the preimage is found.
	LookupPreimage(payhash lntypes.Hash) (lntypes.Preimage, bool)

	// AddPreimages adds a batch of newly discovered preimages to the global
	// cache, and also signals any subscribers of the newly discovered
	// witness.
	AddPreimages(preimages ...lntypes.Preimage) error
}

WitnessBeacon is a global beacon of witnesses. Contract resolvers will use this interface to lookup witnesses (preimages typically) of contracts they're trying to resolve, add new preimages they resolve, and finally receive new updates each new time a preimage is discovered.

TODO(roasbeef): need to delete the pre-images once we've used them and have been sufficiently confirmed?

type WitnessSubscription

type WitnessSubscription struct {
	// WitnessUpdates is a channel that newly discovered witnesses will be
	// sent over.
	//
	// TODO(roasbeef): couple with WitnessType?
	WitnessUpdates <-chan lntypes.Preimage

	// CancelSubscription is a function closure that should be used by a
	// client to cancel the subscription once they are no longer interested
	// in receiving new updates.
	CancelSubscription func()
}

WitnessSubscription represents an intent to be notified once new witnesses are discovered by various active contract resolvers. A contract resolver may use this to be notified of when it can satisfy an incoming contract after we discover the witness for an outgoing contract.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL