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.
This commit is contained in:
Olaoluwa Osuntokun 2017-02-07 19:54:40 -08:00
parent 926f5c84d0
commit e8e53a4b91
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2
2 changed files with 7 additions and 7 deletions

@ -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 {

@ -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