From 46990c412cda825e6fc84d6792401f99186631b7 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 4 Dec 2019 13:30:46 -0800 Subject: [PATCH] channeldb/channel: allow storing empty closes This is preparation for the subsequent commit, allowing us to fix a race condition in the integration test assertions. --- channeldb/channel.go | 22 ++++++++++++++++------ channeldb/channel_test.go | 17 ++++++++++++++--- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/channeldb/channel.go b/channeldb/channel.go index 8a67b8a4..b538a7e2 100644 --- a/channeldb/channel.go +++ b/channeldb/channel.go @@ -956,13 +956,18 @@ func (c *OpenChannel) markBroadcasted(status ChannelStatus, key []byte, c.Lock() defer c.Unlock() - var b bytes.Buffer - if err := WriteElement(&b, closeTx); err != nil { - return err - } + // If a closing tx is provided, we'll generate a closure to write the + // transaction in the appropriate bucket under the given key. + var putClosingTx func(*bbolt.Bucket) error + if closeTx != nil { + var b bytes.Buffer + if err := WriteElement(&b, closeTx); err != nil { + return err + } - putClosingTx := func(chanBucket *bbolt.Bucket) error { - return chanBucket.Put(key, b.Bytes()) + putClosingTx = func(chanBucket *bbolt.Bucket) error { + return chanBucket.Put(key, b.Bytes()) + } } return c.putChanStatus(status, putClosingTx) @@ -1039,6 +1044,11 @@ func (c *OpenChannel) putChanStatus(status ChannelStatus, } for _, f := range fs { + // Skip execution of nil closures. + if f == nil { + continue + } + if err := f(chanBucket); err != nil { return err } diff --git a/channeldb/channel_test.go b/channeldb/channel_test.go index 2d606356..87d69d3a 100644 --- a/channeldb/channel_test.go +++ b/channeldb/channel_test.go @@ -897,13 +897,24 @@ func TestFetchWaitingCloseChannels(t *testing.T) { PreviousOutPoint: channel.FundingOutpoint, }, ) + if err := channel.MarkCommitmentBroadcasted(closeTx); err != nil { t.Fatalf("unable to mark commitment broadcast: %v", err) } - // Modify the close tx deterministically and also mark it as - // coop closed. Later we will test that distinct transactions - // are returned for both coop and force closes. + // Now try to marking a coop close with a nil tx. This should + // succeed, but it shouldn't exit when queried. + if err = channel.MarkCoopBroadcasted(nil); err != nil { + t.Fatalf("unable to mark nil coop broadcast: %v", err) + } + _, err := channel.BroadcastedCooperative() + if err != ErrNoCloseTx { + t.Fatalf("expected no closing tx error, got: %v", err) + } + + // Finally, modify the close tx deterministically and also mark + // it as coop closed. Later we will test that distinct + // transactions are returned for both coop and force closes. closeTx.TxIn[0].PreviousOutPoint.Index ^= 1 if err := channel.MarkCoopBroadcasted(closeTx); err != nil { t.Fatalf("unable to mark coop broadcast: %v", err)