contractcourt+lnrpc+lnd: s/BreachArbiter/BreachArbitrator

Since we have two other examples of XArbitrator, we rename
BreachArbiter to BreachArbitrator to keep things consistent.
The aim is to reduce the amount of lore you need to know to
intuit where things are or what they do.
This commit is contained in:
Keagan McClelland committed 2024-02-06 13:32:47 -07:00
1 parent 47fced69da
commit bc3feba267
9 files changed
+102 -91

No files matched your search

+5 -4
View File
@@ -8,13 +8,14 @@ import (
) )
// breachResolver is a resolver that will handle breached closes. In the // breachResolver is a resolver that will handle breached closes. In the
// future, this will likely take over the duties the current breacharbiter has. // future, this will likely take over the duties the current BreachArbitrator
// has.
type breachResolver struct { type breachResolver struct {
// resolved reflects if the contract has been fully resolved or not. // resolved reflects if the contract has been fully resolved or not.
resolved bool resolved bool
// subscribed denotes whether or not the breach resolver has subscribed // subscribed denotes whether or not the breach resolver has subscribed
// to the breacharbiter for breach resolution. // to the BreachArbitrator for breach resolution.
subscribed bool subscribed bool
// replyChan is closed when the breach arbiter has completed serving // replyChan is closed when the breach arbiter has completed serving
@@ -42,8 +43,8 @@ func (b *breachResolver) ResolverKey() []byte {
return key[:] return key[:]
} }
// Resolve queries the breacharbiter to see if the justice transaction has been // Resolve queries the BreachArbitrator to see if the justice transaction has
// broadcast. // been broadcast.
func (b *breachResolver) Resolve() (ContractResolver, error) { func (b *breachResolver) Resolve() (ContractResolver, error) {
if !b.subscribed { if !b.subscribed {
complete, err := b.SubscribeBreachComplete( complete, err := b.SubscribeBreachComplete(
+47 -41
View File
@@ -53,12 +53,12 @@ var (
// for the first and one for the second level). // for the first and one for the second level).
taprootRetributionBucket = []byte("tap-retribution") taprootRetributionBucket = []byte("tap-retribution")
// errBrarShuttingDown is an error returned if the breacharbiter has // errBrarShuttingDown is an error returned if the BreachArbitrator has
// been signalled to exit. // been signalled to exit.
errBrarShuttingDown = errors.New("breacharbiter shutting down") errBrarShuttingDown = errors.New("BreachArbitrator shutting down")
) )
// ContractBreachEvent is an event the BreachArbiter will receive in case a // ContractBreachEvent is an event the BreachArbitrator will receive in case a
// contract breach is observed on-chain. It contains the necessary information // 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 // to handle the breach, and a ProcessACK closure we will use to ACK the event
// when we have safely stored all the necessary information. // when we have safely stored all the necessary information.
@@ -71,7 +71,7 @@ type ContractBreachEvent struct {
// store. In case storing the information to the store fails, a non-nil // 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 // error should be used. When this closure returns, it means that the
// contract court has marked the channel pending close in the DB, and // contract court has marked the channel pending close in the DB, and
// it is safe for the BreachArbiter to carry on its duty. // it is safe for the BreachArbitrator to carry on its duty.
ProcessACK func(error) ProcessACK func(error)
// BreachRetribution is the information needed to act on this contract // BreachRetribution is the information needed to act on this contract
@@ -94,11 +94,12 @@ const (
) )
// RetributionStorer provides an interface for managing a persistent map from // RetributionStorer provides an interface for managing a persistent map from
// wire.OutPoint -> retributionInfo. Upon learning of a breach, a BreachArbiter // wire.OutPoint -> retributionInfo. Upon learning of a breach, a
// should record the retributionInfo for the breached channel, which serves a // BreachArbitrator should record the retributionInfo for the breached channel,
// checkpoint in the event that retribution needs to be resumed after failure. // which serves a checkpoint in the event that retribution needs to be resumed
// A RetributionStore provides an interface for managing the persisted set, as // after failure. A RetributionStore provides an interface for managing the
// well as mapping user defined functions over the entire on-disk contents. // 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 // Calls to RetributionStore may occur concurrently. A concrete instance of
// RetributionStore should use appropriate synchronization primitives, or // RetributionStore should use appropriate synchronization primitives, or
@@ -125,7 +126,8 @@ type RetributionStorer interface {
} }
// BreachConfig bundles the required subsystems used by the breach arbiter. An // BreachConfig bundles the required subsystems used by the breach arbiter. An
// instance of BreachConfig is passed to newBreachArbiter during instantiation. // instance of BreachConfig is passed to NewBreachArbitrator during
// instantiation.
type BreachConfig struct { type BreachConfig struct {
// CloseLink allows the breach arbiter to shutdown any channel links for // CloseLink allows the breach arbiter to shutdown any channel links for
// which it detects a breach, ensuring now further activity will // which it detects a breach, ensuring now further activity will
@@ -154,9 +156,9 @@ type BreachConfig struct {
// transaction to the network. // transaction to the network.
PublishTransaction func(*wire.MsgTx, string) error PublishTransaction func(*wire.MsgTx, string) error
// ContractBreaches is a channel where the BreachArbiter will receive // ContractBreaches is a channel where the BreachArbitrator will receive
// notifications in the event of a contract breach being observed. A // notifications in the event of a contract breach being observed. A
// ContractBreachEvent must be ACKed by the BreachArbiter, such that // ContractBreachEvent must be ACKed by the BreachArbitrator, such that
// the sending subsystem knows that the event is properly handed off. // the sending subsystem knows that the event is properly handed off.
ContractBreaches <-chan *ContractBreachEvent ContractBreaches <-chan *ContractBreachEvent
@@ -171,7 +173,7 @@ type BreachConfig struct {
Store RetributionStorer Store RetributionStorer
} }
// BreachArbiter is a special subsystem which is responsible for watching and // BreachArbitrator is a special subsystem which is responsible for watching and
// acting on the detection of any attempted uncooperative channel breaches by // acting on the detection of any attempted uncooperative channel breaches by
// channel counterparties. This file essentially acts as deterrence code for // channel counterparties. This file essentially acts as deterrence code for
// those attempting to launch attacks against the daemon. In practice it's // those attempting to launch attacks against the daemon. In practice it's
@@ -179,7 +181,7 @@ type BreachConfig struct {
// important to have it in place just in case we encounter cheating channel // important to have it in place just in case we encounter cheating channel
// counterparties. // counterparties.
// TODO(roasbeef): closures in config for subsystem pointers to decouple? // TODO(roasbeef): closures in config for subsystem pointers to decouple?
type BreachArbiter struct { type BreachArbitrator struct {
started sync.Once started sync.Once
stopped sync.Once stopped sync.Once
@@ -192,19 +194,19 @@ type BreachArbiter struct {
sync.Mutex sync.Mutex
} }
// NewBreachArbiter creates a new instance of a BreachArbiter initialized with // NewBreachArbitrator creates a new instance of a BreachArbitrator initialized
// its dependent objects. // with its dependent objects.
func NewBreachArbiter(cfg *BreachConfig) *BreachArbiter { func NewBreachArbitrator(cfg *BreachConfig) *BreachArbitrator {
return &BreachArbiter{ return &BreachArbitrator{
cfg: cfg, cfg: cfg,
subscriptions: make(map[wire.OutPoint]chan struct{}), subscriptions: make(map[wire.OutPoint]chan struct{}),
quit: make(chan struct{}), quit: make(chan struct{}),
} }
} }
// Start is an idempotent method that officially starts the BreachArbiter along // Start is an idempotent method that officially starts the BreachArbitrator
// with all other goroutines it needs to perform its functions. // along with all other goroutines it needs to perform its functions.
func (b *BreachArbiter) Start() error { func (b *BreachArbitrator) Start() error {
var err error var err error
b.started.Do(func() { b.started.Do(func() {
brarLog.Info("Breach arbiter starting") brarLog.Info("Breach arbiter starting")
@@ -213,7 +215,7 @@ func (b *BreachArbiter) Start() error {
return err return err
} }
func (b *BreachArbiter) start() error { func (b *BreachArbitrator) start() error {
// Load all retributions currently persisted in the retribution store. // Load all retributions currently persisted in the retribution store.
var breachRetInfos map[wire.OutPoint]retributionInfo var breachRetInfos map[wire.OutPoint]retributionInfo
if err := b.cfg.Store.ForAll(func(ret *retributionInfo) error { if err := b.cfg.Store.ForAll(func(ret *retributionInfo) error {
@@ -305,10 +307,10 @@ func (b *BreachArbiter) start() error {
return nil return nil
} }
// Stop is an idempotent method that signals the BreachArbiter to execute a // Stop is an idempotent method that signals the BreachArbitrator to execute a
// graceful shutdown. This function will block until all goroutines spawned by // graceful shutdown. This function will block until all goroutines spawned by
// the BreachArbiter have gracefully exited. // the BreachArbitrator have gracefully exited.
func (b *BreachArbiter) Stop() error { func (b *BreachArbitrator) Stop() error {
b.stopped.Do(func() { b.stopped.Do(func() {
brarLog.Infof("Breach arbiter shutting down...") brarLog.Infof("Breach arbiter shutting down...")
defer brarLog.Debug("Breach arbiter shutdown complete") defer brarLog.Debug("Breach arbiter shutdown complete")
@@ -321,13 +323,13 @@ func (b *BreachArbiter) Stop() error {
// IsBreached queries the breach arbiter's retribution store to see if it is // IsBreached queries the breach arbiter's retribution store to see if it is
// aware of any channel breaches for a particular channel point. // aware of any channel breaches for a particular channel point.
func (b *BreachArbiter) IsBreached(chanPoint *wire.OutPoint) (bool, error) { func (b *BreachArbitrator) IsBreached(chanPoint *wire.OutPoint) (bool, error) {
return b.cfg.Store.IsBreached(chanPoint) return b.cfg.Store.IsBreached(chanPoint)
} }
// SubscribeBreachComplete is used by outside subsystems to be notified of a // SubscribeBreachComplete is used by outside subsystems to be notified of a
// successful breach resolution. // successful breach resolution.
func (b *BreachArbiter) SubscribeBreachComplete(chanPoint *wire.OutPoint, func (b *BreachArbitrator) SubscribeBreachComplete(chanPoint *wire.OutPoint,
c chan struct{}) (bool, error) { c chan struct{}) (bool, error) {
breached, err := b.cfg.Store.IsBreached(chanPoint) breached, err := b.cfg.Store.IsBreached(chanPoint)
@@ -353,9 +355,9 @@ func (b *BreachArbiter) SubscribeBreachComplete(chanPoint *wire.OutPoint,
return false, nil return false, nil
} }
// notifyBreachComplete is used by the BreachArbiter to notify outside // notifyBreachComplete is used by the BreachArbitrator to notify outside
// subsystems that the breach resolution process is complete. // subsystems that the breach resolution process is complete.
func (b *BreachArbiter) notifyBreachComplete(chanPoint *wire.OutPoint) { func (b *BreachArbitrator) notifyBreachComplete(chanPoint *wire.OutPoint) {
b.Lock() b.Lock()
defer b.Unlock() defer b.Unlock()
if c, ok := b.subscriptions[*chanPoint]; ok { if c, ok := b.subscriptions[*chanPoint]; ok {
@@ -366,7 +368,7 @@ func (b *BreachArbiter) notifyBreachComplete(chanPoint *wire.OutPoint) {
delete(b.subscriptions, *chanPoint) delete(b.subscriptions, *chanPoint)
} }
// contractObserver is the primary goroutine for the BreachArbiter. This // contractObserver is the primary goroutine for the BreachArbitrator. This
// goroutine is responsible for handling breach events coming from the // goroutine is responsible for handling breach events coming from the
// contractcourt on the ContractBreaches channel. If a channel breach is // contractcourt on the ContractBreaches channel. If a channel breach is
// detected, then the contractObserver will execute the retribution logic // detected, then the contractObserver will execute the retribution logic
@@ -374,7 +376,7 @@ func (b *BreachArbiter) notifyBreachComplete(chanPoint *wire.OutPoint) {
// wallet. // wallet.
// //
// NOTE: This MUST be run as a goroutine. // NOTE: This MUST be run as a goroutine.
func (b *BreachArbiter) contractObserver() { func (b *BreachArbitrator) contractObserver() {
defer b.wg.Done() defer b.wg.Done()
brarLog.Infof("Starting contract observer, watching for breaches.") brarLog.Infof("Starting contract observer, watching for breaches.")
@@ -406,7 +408,7 @@ type spend struct {
// returns the spend details for those outputs. The spendNtfns map is a cache // returns the spend details for those outputs. The spendNtfns map is a cache
// used to store registered spend subscriptions, in case we must call this // used to store registered spend subscriptions, in case we must call this
// method multiple times. // method multiple times.
func (b *BreachArbiter) waitForSpendEvent(breachInfo *retributionInfo, func (b *BreachArbitrator) waitForSpendEvent(breachInfo *retributionInfo,
spendNtfns map[wire.OutPoint]*chainntnfs.SpendEvent) ([]spend, error) { spendNtfns map[wire.OutPoint]*chainntnfs.SpendEvent) ([]spend, error) {
inputs := breachInfo.breachedOutputs inputs := breachInfo.breachedOutputs
@@ -684,8 +686,10 @@ func updateBreachInfo(breachInfo *retributionInfo, spends []spend) (
// the lingering funds within the channel into the daemon's wallet. // the lingering funds within the channel into the daemon's wallet.
// //
// NOTE: This MUST be run as a goroutine. // NOTE: This MUST be run as a goroutine.
func (b *BreachArbiter) exactRetribution(confChan *chainntnfs.ConfirmationEvent, //
breachInfo *retributionInfo) { //nolint:funlen
func (b *BreachArbitrator) exactRetribution(
confChan *chainntnfs.ConfirmationEvent, breachInfo *retributionInfo) {
defer b.wg.Done() defer b.wg.Done()
@@ -916,7 +920,7 @@ Loop:
// cleanupBreach marks the given channel point as fully resolved and removes the // cleanupBreach marks the given channel point as fully resolved and removes the
// retribution for that the channel from the retribution store. // retribution for that the channel from the retribution store.
func (b *BreachArbiter) cleanupBreach(chanPoint *wire.OutPoint) error { func (b *BreachArbitrator) cleanupBreach(chanPoint *wire.OutPoint) error {
// With the channel closed, mark it in the database as such. // With the channel closed, mark it in the database as such.
err := b.cfg.DB.MarkChanFullyClosed(chanPoint) err := b.cfg.DB.MarkChanFullyClosed(chanPoint)
if err != nil { if err != nil {
@@ -943,15 +947,17 @@ func (b *BreachArbiter) cleanupBreach(chanPoint *wire.OutPoint) error {
} }
// handleBreachHandoff handles a new breach event, by writing it to disk, then // handleBreachHandoff handles a new breach event, by writing it to disk, then
// notifies the BreachArbiter contract observer goroutine that a channel's // notifies the BreachArbitrator contract observer goroutine that a channel's
// contract has been breached by the prior counterparty. Once notified the // contract has been breached by the prior counterparty. Once notified the
// BreachArbiter will attempt to sweep ALL funds within the channel using the // BreachArbitrator will attempt to sweep ALL funds within the channel using the
// information provided within the BreachRetribution generated due to the // information provided within the BreachRetribution generated due to the
// breach of channel contract. The funds will be swept only after the breaching // breach of channel contract. The funds will be swept only after the breaching
// transaction receives a necessary number of confirmations. // transaction receives a necessary number of confirmations.
// //
// NOTE: This MUST be run as a goroutine. // NOTE: This MUST be run as a goroutine.
func (b *BreachArbiter) handleBreachHandoff(breachEvent *ContractBreachEvent) { func (b *BreachArbitrator) handleBreachHandoff(
breachEvent *ContractBreachEvent) {
defer b.wg.Done() defer b.wg.Done()
chanPoint := breachEvent.ChanPoint chanPoint := breachEvent.ChanPoint
@@ -1367,7 +1373,7 @@ type justiceTxVariants struct {
// the funds within the channel which we are now entitled to due to a breach of // the funds within the channel which we are now entitled to due to a breach of
// the channel's contract by the counterparty. This function returns a *fully* // the channel's contract by the counterparty. This function returns a *fully*
// signed transaction with the witness for each input fully in place. // signed transaction with the witness for each input fully in place.
func (b *BreachArbiter) createJusticeTx( func (b *BreachArbitrator) createJusticeTx(
breachedOutputs []breachedOutput) (*justiceTxVariants, error) { breachedOutputs []breachedOutput) (*justiceTxVariants, error) {
var ( var (
@@ -1442,7 +1448,7 @@ func (b *BreachArbiter) createJusticeTx(
} }
// createSweepTx creates a tx that sweeps the passed inputs back to our wallet. // createSweepTx creates a tx that sweeps the passed inputs back to our wallet.
func (b *BreachArbiter) createSweepTx(inputs ...input.Input) (*wire.MsgTx, func (b *BreachArbitrator) createSweepTx(inputs ...input.Input) (*wire.MsgTx,
error) { error) {
if len(inputs) == 0 { if len(inputs) == 0 {
@@ -1498,7 +1504,7 @@ func (b *BreachArbiter) createSweepTx(inputs ...input.Input) (*wire.MsgTx,
// sweepSpendableOutputsTxn creates a signed transaction from a sequence of // sweepSpendableOutputsTxn creates a signed transaction from a sequence of
// spendable outputs by sweeping the funds into a single p2wkh output. // spendable outputs by sweeping the funds into a single p2wkh output.
func (b *BreachArbiter) sweepSpendableOutputsTxn(txWeight int64, func (b *BreachArbitrator) sweepSpendableOutputsTxn(txWeight int64,
inputs ...input.Input) (*wire.MsgTx, error) { inputs ...input.Input) (*wire.MsgTx, error) {
// First, we obtain a new public key script from the wallet which we'll // First, we obtain a new public key script from the wallet which we'll
+9 -9
View File
@@ -951,7 +951,7 @@ restartCheck:
} }
} }
func initBreachedState(t *testing.T) (*BreachArbiter, func initBreachedState(t *testing.T) (*BreachArbitrator,
*lnwallet.LightningChannel, *lnwallet.LightningChannel, *lnwallet.LightningChannel, *lnwallet.LightningChannel,
*lnwallet.LocalForceCloseSummary, chan *ContractBreachEvent) { *lnwallet.LocalForceCloseSummary, chan *ContractBreachEvent) {
@@ -1338,7 +1338,7 @@ func getSpendTransactions(signer input.Signer, chanPoint *wire.OutPoint,
}, },
} }
// In order for the breacharbiter to detect that it is being spent // In order for the BreachArbitrator to detect that it is being spent
// using the revocation key, it will inspect the witness. Therefore // using the revocation key, it will inspect the witness. Therefore
// sign and add the witness to the HTLC sweep. // sign and add the witness to the HTLC sweep.
retInfo := newRetributionInfo(chanPoint, retribution) retInfo := newRetributionInfo(chanPoint, retribution)
@@ -1684,7 +1684,7 @@ func testBreachSpends(t *testing.T, test breachTest) {
} }
// We also keep a map of those remaining outputs we expect the // We also keep a map of those remaining outputs we expect the
// breacharbiter to try and sweep. // BreachArbitrator to try and sweep.
inputsToSweep := map[wire.OutPoint]struct{}{ inputsToSweep := map[wire.OutPoint]struct{}{
htlcOutpoint: {}, htlcOutpoint: {},
localOutpoint: {}, localOutpoint: {},
@@ -1892,7 +1892,7 @@ func TestBreachDelayedJusticeConfirmation(t *testing.T) {
} }
// Now mine another block without the justice tx confirming. This // Now mine another block without the justice tx confirming. This
// should lead to the breacharbiter publishing the split justice tx // should lead to the BreachArbitrator publishing the split justice tx
// variants. // variants.
notifier.EpochChan <- &chainntnfs.BlockEpoch{ notifier.EpochChan <- &chainntnfs.BlockEpoch{
Height: blockHeight + 4, Height: blockHeight + 4,
@@ -1988,7 +1988,7 @@ func findInputIndex(t *testing.T, op wire.OutPoint, tx *wire.MsgTx) int {
// assertArbiterBreach checks that the breach arbiter has persisted the breach // assertArbiterBreach checks that the breach arbiter has persisted the breach
// information for a particular channel. // information for a particular channel.
func assertArbiterBreach(t *testing.T, brar *BreachArbiter, func assertArbiterBreach(t *testing.T, brar *BreachArbitrator,
chanPoint *wire.OutPoint) { chanPoint *wire.OutPoint) {
t.Helper() t.Helper()
@@ -2008,7 +2008,7 @@ func assertArbiterBreach(t *testing.T, brar *BreachArbiter,
// assertNoArbiterBreach checks that the breach arbiter has not persisted the // assertNoArbiterBreach checks that the breach arbiter has not persisted the
// breach information for a particular channel. // breach information for a particular channel.
func assertNoArbiterBreach(t *testing.T, brar *BreachArbiter, func assertNoArbiterBreach(t *testing.T, brar *BreachArbitrator,
chanPoint *wire.OutPoint) { chanPoint *wire.OutPoint) {
t.Helper() t.Helper()
@@ -2027,7 +2027,7 @@ func assertNoArbiterBreach(t *testing.T, brar *BreachArbiter,
// assertBrarCleanup blocks until the given channel point has been removed the // assertBrarCleanup blocks until the given channel point has been removed the
// retribution store and the channel is fully closed in the database. // retribution store and the channel is fully closed in the database.
func assertBrarCleanup(t *testing.T, brar *BreachArbiter, func assertBrarCleanup(t *testing.T, brar *BreachArbitrator,
chanPoint *wire.OutPoint, db *channeldb.ChannelStateDB) { chanPoint *wire.OutPoint, db *channeldb.ChannelStateDB) {
t.Helper() t.Helper()
@@ -2108,7 +2108,7 @@ func assertNotPendingClosed(t *testing.T, c *lnwallet.LightningChannel) {
// createTestArbiter instantiates a breach arbiter with a failing retribution // createTestArbiter instantiates a breach arbiter with a failing retribution
// store, so that controlled failures can be tested. // store, so that controlled failures can be tested.
func createTestArbiter(t *testing.T, contractBreaches chan *ContractBreachEvent, func createTestArbiter(t *testing.T, contractBreaches chan *ContractBreachEvent,
db *channeldb.DB) (*BreachArbiter, error) { db *channeldb.DB) (*BreachArbitrator, error) {
// Create a failing retribution store, that wraps a normal one. // Create a failing retribution store, that wraps a normal one.
store := newFailingRetributionStore(func() RetributionStorer { store := newFailingRetributionStore(func() RetributionStorer {
@@ -2120,7 +2120,7 @@ func createTestArbiter(t *testing.T, contractBreaches chan *ContractBreachEvent,
// Assemble our test arbiter. // Assemble our test arbiter.
notifier := mock.MakeMockSpendNotifier() notifier := mock.MakeMockSpendNotifier()
ba := NewBreachArbiter(&BreachConfig{ ba := NewBreachArbitrator(&BreachConfig{
CloseLink: func(_ *wire.OutPoint, _ ChannelCloseType) {}, CloseLink: func(_ *wire.OutPoint, _ ChannelCloseType) {},
DB: db.ChannelStateDB(), DB: db.ChannelStateDB(),
Estimator: chainfee.NewStaticEstimator(12500, 0), Estimator: chainfee.NewStaticEstimator(12500, 0),
+3 -3
View File
@@ -100,10 +100,10 @@ type ChainArbitratorConfig struct {
MarkLinkInactive func(wire.OutPoint) error MarkLinkInactive func(wire.OutPoint) error
// ContractBreach is a function closure that the ChainArbitrator will // ContractBreach is a function closure that the ChainArbitrator will
// use to notify the breachArbiter about a contract breach. It should // use to notify the BreachArbitrator about a contract breach. It should
// only return a non-nil error when the breachArbiter has preserved // only return a non-nil error when the BreachArbitrator has preserved
// the necessary breach info for this channel point. Once the breach // the necessary breach info for this channel point. Once the breach
// resolution is persisted in the channel arbitrator, it will be safe // resolution is persisted in the ChannelArbitrator, it will be safe
// to mark the channel closed. // to mark the channel closed.
ContractBreach func(wire.OutPoint, *lnwallet.BreachRetribution) error ContractBreach func(wire.OutPoint, *lnwallet.BreachRetribution) error
+3 -3
View File
@@ -175,7 +175,7 @@ type chainWatcherConfig struct {
// contractBreach is a method that will be called by the watcher if it // contractBreach is a method that will be called by the watcher if it
// detects that a contract breach transaction has been confirmed. It // detects that a contract breach transaction has been confirmed. It
// will only return a non-nil error when the breachArbiter has // will only return a non-nil error when the BreachArbitrator has
// preserved the necessary breach info for this channel point. // preserved the necessary breach info for this channel point.
contractBreach func(*lnwallet.BreachRetribution) error contractBreach func(*lnwallet.BreachRetribution) error
@@ -1243,14 +1243,14 @@ func (c *chainWatcher) dispatchContractBreach(spendEvent *chainntnfs.SpendDetail
closeSummary.LastChanSyncMsg = chanSync closeSummary.LastChanSyncMsg = chanSync
} }
// Hand the retribution info over to the breach arbiter. This function // Hand the retribution info over to the BreachArbitrator. This function
// will wait for a response from the breach arbiter and then proceed to // will wait for a response from the breach arbiter and then proceed to
// send a BreachCloseInfo to the channel arbitrator. The channel arb // send a BreachCloseInfo to the channel arbitrator. The channel arb
// will then mark the channel as closed after resolutions and the // will then mark the channel as closed after resolutions and the
// commit set are logged in the arbitrator log. // commit set are logged in the arbitrator log.
if err := c.cfg.contractBreach(retribution); err != nil { if err := c.cfg.contractBreach(retribution); err != nil {
log.Errorf("unable to hand breached contract off to "+ log.Errorf("unable to hand breached contract off to "+
"breachArbiter: %v", err) "BreachArbitrator: %v", err)
return err return err
} }
+3 -3
View File
@@ -860,7 +860,7 @@ const (
// breachCloseTrigger is a transition trigger driven by a remote breach // breachCloseTrigger is a transition trigger driven by a remote breach
// being confirmed. In this case the channel arbitrator will wait for // being confirmed. In this case the channel arbitrator will wait for
// the breacharbiter to finish and then clean up gracefully. // the BreachArbitrator to finish and then clean up gracefully.
breachCloseTrigger breachCloseTrigger
) )
@@ -2891,7 +2891,7 @@ func (c *ChannelArbitrator) channelAttendant(bestHeight int32) {
} }
// The remote has breached the channel. As this is handled by // The remote has breached the channel. As this is handled by
// the ChainWatcher and BreachArbiter, we don't have to do // the ChainWatcher and BreachArbitrator, we don't have to do
// anything in particular, so just advance our state and // anything in particular, so just advance our state and
// gracefully exit. // gracefully exit.
case breachInfo := <-c.cfg.ChainEvents.ContractBreach: case breachInfo := <-c.cfg.ChainEvents.ContractBreach:
@@ -2926,7 +2926,7 @@ func (c *ChannelArbitrator) channelAttendant(bestHeight int32) {
} }
// The channel is finally marked pending closed here as // The channel is finally marked pending closed here as
// the breacharbiter and channel arbitrator have // the BreachArbitrator and channel arbitrator have
// persisted the relevant states. // persisted the relevant states.
closeSummary := &breachInfo.CloseSummary closeSummary := &breachInfo.CloseSummary
err = c.cfg.MarkChannelClosed( err = c.cfg.MarkChannelClosed(
+1 -1
View File
@@ -1430,7 +1430,7 @@ func TestChannelArbitratorPersistence(t *testing.T) {
// is breached by the remote node. In these cases we expect the // is breached by the remote node. In these cases we expect the
// ChannelArbitrator to properly execute the breachResolver flow and then // ChannelArbitrator to properly execute the breachResolver flow and then
// gracefully exit once the breachResolver receives the signal from what would // gracefully exit once the breachResolver receives the signal from what would
// normally be the breacharbiter. // normally be the BreachArbitrator.
func TestChannelArbitratorForceCloseBreachedChannel(t *testing.T) { func TestChannelArbitratorForceCloseBreachedChannel(t *testing.T) {
log := &mockArbitratorLog{ log := &mockArbitratorLog{
state: StateDefault, state: StateDefault,
+1 -1
View File
@@ -201,7 +201,7 @@ var (
// are numbered differently. The protobuf enum cannot be renumbered // are numbered differently. The protobuf enum cannot be renumbered
// because this would break backwards compatibility with older clients, // because this would break backwards compatibility with older clients,
// and the native enum cannot be renumbered because it is stored in the // and the native enum cannot be renumbered because it is stored in the
// watchtower and breacharbiter databases. // watchtower and BreachArbitrator databases.
// //
//nolint:lll //nolint:lll
allWitnessTypes = map[input.WitnessType]WitnessType{ allWitnessTypes = map[input.WitnessType]WitnessType{
+30 -26
View File
@@ -262,7 +262,7 @@ type server struct {
witnessBeacon contractcourt.WitnessBeacon witnessBeacon contractcourt.WitnessBeacon
breachArbiter *contractcourt.BreachArbiter breachArbitrator *contractcourt.BreachArbitrator
missionControl *routing.MissionControl missionControl *routing.MissionControl
@@ -1099,22 +1099,24 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
} }
// We will use the following channel to reliably hand off contract // We will use the following channel to reliably hand off contract
// breach events from the ChannelArbitrator to the breachArbiter, // breach events from the ChannelArbitrator to the BreachArbitrator,
contractBreaches := make(chan *contractcourt.ContractBreachEvent, 1) contractBreaches := make(chan *contractcourt.ContractBreachEvent, 1)
s.breachArbiter = contractcourt.NewBreachArbiter(&contractcourt.BreachConfig{ s.breachArbitrator = contractcourt.NewBreachArbitrator(
CloseLink: closeLink, &contractcourt.BreachConfig{
DB: s.chanStateDB, CloseLink: closeLink,
Estimator: s.cc.FeeEstimator, DB: s.chanStateDB,
GenSweepScript: newSweepPkScriptGen(cc.Wallet), Estimator: s.cc.FeeEstimator,
Notifier: cc.ChainNotifier, GenSweepScript: newSweepPkScriptGen(cc.Wallet),
PublishTransaction: cc.Wallet.PublishTransaction, Notifier: cc.ChainNotifier,
ContractBreaches: contractBreaches, PublishTransaction: cc.Wallet.PublishTransaction,
Signer: cc.Wallet.Cfg.Signer, ContractBreaches: contractBreaches,
Store: contractcourt.NewRetributionStore( Signer: cc.Wallet.Cfg.Signer,
dbs.ChanStateDB, Store: contractcourt.NewRetributionStore(
), dbs.ChanStateDB,
}) ),
},
)
s.chainArb = contractcourt.NewChainArbitrator(contractcourt.ChainArbitratorConfig{ s.chainArb = contractcourt.NewChainArbitrator(contractcourt.ChainArbitratorConfig{
ChainHash: *s.cfg.ActiveNetParams.GenesisHash, ChainHash: *s.cfg.ActiveNetParams.GenesisHash,
@@ -1167,8 +1169,8 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
ContractBreach: func(chanPoint wire.OutPoint, ContractBreach: func(chanPoint wire.OutPoint,
breachRet *lnwallet.BreachRetribution) error { breachRet *lnwallet.BreachRetribution) error {
// processACK will handle the breachArbiter ACKing the // processACK will handle the BreachArbitrator ACKing
// event. // the event.
finalErr := make(chan error, 1) finalErr := make(chan error, 1)
processACK := func(brarErr error) { processACK := func(brarErr error) {
if brarErr != nil { if brarErr != nil {
@@ -1176,7 +1178,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
return return
} }
// If the breachArbiter successfully handled // If the BreachArbitrator successfully handled
// the event, we can signal that the handoff // the event, we can signal that the handoff
// was successful. // was successful.
finalErr <- nil finalErr <- nil
@@ -1188,7 +1190,8 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
BreachRetribution: breachRet, BreachRetribution: breachRet,
} }
// Send the contract breach event to the breachArbiter. // Send the contract breach event to the
// BreachArbitrator.
select { select {
case contractBreaches <- event: case contractBreaches <- event:
case <-s.quit: case <-s.quit:
@@ -1196,7 +1199,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
} }
// We'll wait for a final error to be available from // We'll wait for a final error to be available from
// the breachArbiter. // the BreachArbitrator.
select { select {
case err := <-finalErr: case err := <-finalErr:
return err return err
@@ -1215,8 +1218,8 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
PaymentsExpirationGracePeriod: cfg.PaymentsExpirationGracePeriod, PaymentsExpirationGracePeriod: cfg.PaymentsExpirationGracePeriod,
IsForwardedHTLC: s.htlcSwitch.IsForwardedHTLC, IsForwardedHTLC: s.htlcSwitch.IsForwardedHTLC,
Clock: clock.NewDefaultClock(), Clock: clock.NewDefaultClock(),
SubscribeBreachComplete: s.breachArbiter.SubscribeBreachComplete, SubscribeBreachComplete: s.breachArbitrator.SubscribeBreachComplete, //nolint:lll
PutFinalHtlcOutcome: s.chanStateDB.PutOnchainFinalHtlcOutcome, //nolint: lll PutFinalHtlcOutcome: s.chanStateDB.PutOnchainFinalHtlcOutcome, //nolint: lll
HtlcNotifier: s.htlcNotifier, HtlcNotifier: s.htlcNotifier,
}, dbs.ChanStateDB) }, dbs.ChanStateDB)
@@ -1936,11 +1939,11 @@ func (s *server) Start() error {
} }
cleanup = cleanup.add(s.utxoNursery.Stop) cleanup = cleanup.add(s.utxoNursery.Stop)
if err := s.breachArbiter.Start(); err != nil { if err := s.breachArbitrator.Start(); err != nil {
startErr = err startErr = err
return return
} }
cleanup = cleanup.add(s.breachArbiter.Stop) cleanup = cleanup.add(s.breachArbitrator.Stop)
if err := s.fundingMgr.Start(); err != nil { if err := s.fundingMgr.Start(); err != nil {
startErr = err startErr = err
@@ -2244,8 +2247,9 @@ func (s *server) Stop() error {
if err := s.fundingMgr.Stop(); err != nil { if err := s.fundingMgr.Stop(); err != nil {
srvrLog.Warnf("failed to stop fundingMgr: %v", err) srvrLog.Warnf("failed to stop fundingMgr: %v", err)
} }
if err := s.breachArbiter.Stop(); err != nil { if err := s.breachArbitrator.Stop(); err != nil {
srvrLog.Warnf("failed to stop breachArbiter: %v", err) srvrLog.Warnf("failed to stop breachArbitrator: %v",
err)
} }
if err := s.utxoNursery.Stop(); err != nil { if err := s.utxoNursery.Stop(); err != nil {
srvrLog.Warnf("failed to stop utxoNursery: %v", err) srvrLog.Warnf("failed to stop utxoNursery: %v", err)