From ac0e9b60169515726bad5400ab21851e46669117 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Fri, 6 Sep 2019 13:14:39 +0200 Subject: [PATCH] channeldb/channel: add BroadcastedCommitment --- channeldb/channel.go | 35 +++++++++++++++++++++++++++++++++++ channeldb/channel_test.go | 20 +++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/channeldb/channel.go b/channeldb/channel.go index 79416a28..3db55e08 100644 --- a/channeldb/channel.go +++ b/channeldb/channel.go @@ -108,6 +108,10 @@ var ( // in the database. ErrNoCommitPoint = fmt.Errorf("no commit point found") + // ErrNoCloseTx is returned when no closing tx is found for a channel + // in the state CommitBroadcasted. + ErrNoCloseTx = fmt.Errorf("no closing tx found") + // ErrNoRestoredChannelMutation is returned when a caller attempts to // mutate a channel that's been recovered. ErrNoRestoredChannelMutation = fmt.Errorf("cannot mutate restored " + @@ -902,6 +906,37 @@ func (c *OpenChannel) MarkCommitmentBroadcasted(closeTx *wire.MsgTx) error { return c.putChanStatus(ChanStatusCommitBroadcasted, putClosingTx) } +// BroadcastedCommitment retrieves the stored closing tx set during +// MarkCommitmentBroadcasted. If not found ErrNoCloseTx is returned. +func (c *OpenChannel) BroadcastedCommitment() (*wire.MsgTx, error) { + var closeTx *wire.MsgTx + + err := c.Db.View(func(tx *bbolt.Tx) error { + chanBucket, err := fetchChanBucket( + tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash, + ) + switch err { + case nil: + case ErrNoChanDBExists, ErrNoActiveChannels, ErrChannelNotFound: + return ErrNoCloseTx + default: + return err + } + + bs := chanBucket.Get(closingTxKey) + if bs == nil { + return ErrNoCloseTx + } + r := bytes.NewReader(bs) + return ReadElement(r, &closeTx) + }) + if err != nil { + return nil, err + } + + return closeTx, nil +} + // putChanStatus appends the given status to the channel. fs is an optional // list of closures that are given the chanBucket in order to atomically add // extra information together with the new status. diff --git a/channeldb/channel_test.go b/channeldb/channel_test.go index ad03d4ea..21bb738c 100644 --- a/channeldb/channel_test.go +++ b/channeldb/channel_test.go @@ -891,7 +891,12 @@ 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 { - closeTx := &wire.MsgTx{} + closeTx := wire.NewMsgTx(2) + closeTx.AddTxIn( + &wire.TxIn{ + PreviousOutPoint: channel.FundingOutpoint, + }, + ) if err := channel.MarkCommitmentBroadcasted(closeTx); err != nil { t.Fatalf("unable to mark commitment broadcast: %v", err) } @@ -917,6 +922,19 @@ func TestFetchWaitingCloseChannels(t *testing.T) { t.Fatalf("expected channel %v to be waiting close", channel.FundingOutpoint) } + + // Finally, make sure we can retrieve the closing tx for the + // channel. + closeTx, err := channel.BroadcastedCommitment() + if err != nil { + t.Fatalf("Unable to retrieve commitment: %v", err) + } + + if closeTx.TxIn[0].PreviousOutPoint != channel.FundingOutpoint { + t.Fatalf("expected outpoint %v, got %v", + channel.FundingOutpoint, + closeTx.TxIn[0].PreviousOutPoint) + } } }