From e8e53a4b91d94b9920f3925db224d7c771b58521 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Tue, 7 Feb 2017 19:54:40 -0800 Subject: [PATCH] channeldb: fix channel corruption bug upon channel closure This commit fixes a bug which would previously lead to corruption of the channel state when a node had one or more channels open and one of them was closed either forcibly or cooperatively. The source of the bug itself as a typo: rather than using the construed `deliveryKey` variable to fetch/put/delete the delivery scripts, `deliveryScriptsKey` (the key prefix itself) as used. This bug would cause the database to be unable to read _any_ channel from the database after one was deleted, as each channel would actually be reading/writing-to the _exact same_ delivery script. The fix for the bug itself is simple: eliminate the typo. --- channeldb/channel.go | 12 ++++++------ channeldb/db.go | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/channeldb/channel.go b/channeldb/channel.go index 8635e106..1b5fdecd 100644 --- a/channeldb/channel.go +++ b/channeldb/channel.go @@ -293,7 +293,7 @@ func (c *OpenChannel) fullSync(tx *bolt.Tx) error { // Add this channel ID to the node's active channel index if // it doesn't already exist. - chanIDBucket, err := nodeChanBucket.CreateBucketIfNotExists(chanIDBucket) + chanIndexBucket, err := nodeChanBucket.CreateBucketIfNotExists(chanIDBucket) if err != nil { return err } @@ -301,8 +301,8 @@ func (c *OpenChannel) fullSync(tx *bolt.Tx) error { if err := writeOutpoint(&b, c.ChanID); err != nil { return err } - if chanIDBucket.Get(b.Bytes()) == nil { - if err := chanIDBucket.Put(b.Bytes(), nil); err != nil { + if chanIndexBucket.Get(b.Bytes()) == nil { + if err := chanIndexBucket.Put(b.Bytes(), nil); err != nil { return err } } @@ -1579,14 +1579,14 @@ func putChanDeliveryScripts(nodeChanBucket *bolt.Bucket, channel *OpenChannel) e return err } - return nodeChanBucket.Put(deliveryScriptsKey, b.Bytes()) + return nodeChanBucket.Put(deliveryKey, b.Bytes()) } func deleteChanDeliveryScripts(nodeChanBucket *bolt.Bucket, chanID []byte) error { deliveryKey := make([]byte, len(deliveryScriptsKey)+len(chanID)) copy(deliveryKey[:3], deliveryScriptsKey) copy(deliveryKey[3:], chanID) - return nodeChanBucket.Delete(deliveryScriptsKey) + return nodeChanBucket.Delete(deliveryKey) } func fetchChanDeliveryScripts(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error { @@ -1599,7 +1599,7 @@ func fetchChanDeliveryScripts(nodeChanBucket *bolt.Bucket, channel *OpenChannel) copy(deliveryKey[3:], b.Bytes()) var err error - deliveryBytes := bytes.NewReader(nodeChanBucket.Get(deliveryScriptsKey)) + deliveryBytes := bytes.NewReader(nodeChanBucket.Get(deliveryKey)) channel.OurDeliveryScript, err = wire.ReadVarBytes(deliveryBytes, 0, 520, "") if err != nil { diff --git a/channeldb/db.go b/channeldb/db.go index 4b07fb76..056ebdbd 100644 --- a/channeldb/db.go +++ b/channeldb/db.go @@ -276,7 +276,7 @@ func (d *DB) fetchNodeChannels(openChanBucket, nodeChanBucket, chanID) if err != nil { return fmt.Errorf("unable to read channel data for "+ - "chan_point=%v", chanID) + "chan_point=%v: %v", chanID, err) } oChannel.Db = d