From 02b2787e4482ec4d8a37dd5f76db66dee79c5df6 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Fri, 6 Sep 2019 13:14:39 +0200 Subject: [PATCH] multi: make MarkCommitmentBroadcasted take closeTx --- chancloser.go | 4 +++- channeldb/channel.go | 22 +++++++++++++++++++--- channeldb/channel_test.go | 3 ++- contractcourt/channel_arbitrator.go | 4 ++-- contractcourt/channel_arbitrator_test.go | 2 +- lnwallet/channel.go | 4 ++-- 6 files changed, 29 insertions(+), 10 deletions(-) diff --git a/chancloser.go b/chancloser.go index be8395cec..d78a3824d 100644 --- a/chancloser.go +++ b/chancloser.go @@ -444,7 +444,9 @@ func (c *channelCloser) ProcessCloseMsg(msg lnwire.Message) ([]lnwire.Message, b if err := c.cfg.broadcastTx(closeTx); err != nil { return nil, false, err } - if err := c.cfg.channel.MarkCommitmentBroadcasted(); err != nil { + + err = c.cfg.channel.MarkCommitmentBroadcasted(closeTx) + if err != nil { return nil, false, err } diff --git a/channeldb/channel.go b/channeldb/channel.go index 701040002..79416a284 100644 --- a/channeldb/channel.go +++ b/channeldb/channel.go @@ -59,6 +59,10 @@ var ( // remote peer during a channel sync in case we have lost channel state. dataLossCommitPointKey = []byte("data-loss-commit-point-key") + // closingTxKey points to a the closing tx that we broadcasted when + // moving the channel to state CommitBroadcasted. + closingTxKey = []byte("closing-tx-key") + // commitDiffKey stores the current pending commitment state we've // extended to the remote party (if any). Each time we propose a new // state, we store the information necessary to reconstruct this state @@ -878,12 +882,24 @@ func (c *OpenChannel) isBorked(chanBucket *bbolt.Bucket) (bool, error) { // MarkCommitmentBroadcasted marks the channel as a commitment transaction has // been broadcast, either our own or the remote, and we should watch the chain -// for it to confirm before taking any further action. -func (c *OpenChannel) MarkCommitmentBroadcasted() error { +// for it to confirm before taking any further action. It takes as argument the +// closing tx _we believe_ will appear in the chain. This is only used to +// republish this tx at startup to ensure propagation, and we should still +// handle the case where a different tx actually hits the chain. +func (c *OpenChannel) MarkCommitmentBroadcasted(closeTx *wire.MsgTx) error { c.Lock() defer c.Unlock() - return c.putChanStatus(ChanStatusCommitBroadcasted) + var b bytes.Buffer + if err := WriteElement(&b, closeTx); err != nil { + return err + } + + putClosingTx := func(chanBucket *bbolt.Bucket) error { + return chanBucket.Put(closingTxKey, b.Bytes()) + } + + return c.putChanStatus(ChanStatusCommitBroadcasted, putClosingTx) } // putChanStatus appends the given status to the channel. fs is an optional diff --git a/channeldb/channel_test.go b/channeldb/channel_test.go index 46ac311cc..ad03d4ea9 100644 --- a/channeldb/channel_test.go +++ b/channeldb/channel_test.go @@ -891,7 +891,8 @@ func TestFetchWaitingCloseChannels(t *testing.T) { // This would happen in the event of a force close and should make the // channels enter a state of waiting close. for _, channel := range channels { - if err := channel.MarkCommitmentBroadcasted(); err != nil { + closeTx := &wire.MsgTx{} + if err := channel.MarkCommitmentBroadcasted(closeTx); err != nil { t.Fatalf("unable to mark commitment broadcast: %v", err) } } diff --git a/contractcourt/channel_arbitrator.go b/contractcourt/channel_arbitrator.go index fbad14651..c15d855e7 100644 --- a/contractcourt/channel_arbitrator.go +++ b/contractcourt/channel_arbitrator.go @@ -97,7 +97,7 @@ type ChannelArbitratorConfig struct { // MarkCommitmentBroadcasted should mark the channel as the commitment // being broadcast, and we are waiting for the commitment to confirm. - MarkCommitmentBroadcasted func() error + MarkCommitmentBroadcasted func(*wire.MsgTx) error // MarkChannelClosed marks the channel closed in the database, with the // passed close summary. After this method successfully returns we can @@ -840,7 +840,7 @@ func (c *ChannelArbitrator) stateStep( } } - if err := c.cfg.MarkCommitmentBroadcasted(); err != nil { + if err := c.cfg.MarkCommitmentBroadcasted(closeTx); err != nil { log.Errorf("ChannelArbitrator(%v): unable to "+ "mark commitment broadcasted: %v", c.cfg.ChanPoint, err) diff --git a/contractcourt/channel_arbitrator_test.go b/contractcourt/channel_arbitrator_test.go index b785b02ae..f98fe1161 100644 --- a/contractcourt/channel_arbitrator_test.go +++ b/contractcourt/channel_arbitrator_test.go @@ -213,7 +213,7 @@ func createTestChannelArbitrator(log ArbitratorLog) (*ChannelArbitrator, } return summary, nil }, - MarkCommitmentBroadcasted: func() error { + MarkCommitmentBroadcasted: func(_ *wire.MsgTx) error { return nil }, MarkChannelClosed: func(*channeldb.ChannelCloseSummary) error { diff --git a/lnwallet/channel.go b/lnwallet/channel.go index 3e6ef764c..00a7f0dba 100644 --- a/lnwallet/channel.go +++ b/lnwallet/channel.go @@ -6259,11 +6259,11 @@ func (lc *LightningChannel) State() *channeldb.OpenChannel { // MarkCommitmentBroadcasted marks the channel as a commitment transaction has // been broadcast, either our own or the remote, and we should watch the chain // for it to confirm before taking any further action. -func (lc *LightningChannel) MarkCommitmentBroadcasted() error { +func (lc *LightningChannel) MarkCommitmentBroadcasted(tx *wire.MsgTx) error { lc.Lock() defer lc.Unlock() - return lc.channelState.MarkCommitmentBroadcasted() + return lc.channelState.MarkCommitmentBroadcasted(tx) } // ActiveHtlcs returns a slice of HTLC's which are currently active on *both*