channeldb: avoid modifying bucket during cursor traversal
This is not safe according to bbolt documentation.
This commit is contained in:
parent
ed8d635cf1
commit
f98f452528
@ -2087,10 +2087,6 @@ func (c *OpenChannel) CloseChannel(summary *ChannelCloseSummary) error {
|
|||||||
// information stored within the revocation log.
|
// information stored within the revocation log.
|
||||||
logBucket := chanBucket.Bucket(revocationLogBucket)
|
logBucket := chanBucket.Bucket(revocationLogBucket)
|
||||||
if logBucket != nil {
|
if logBucket != nil {
|
||||||
err := wipeChannelLogEntries(logBucket)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = chanBucket.DeleteBucket(revocationLogBucket)
|
err = chanBucket.DeleteBucket(revocationLogBucket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -2713,16 +2709,3 @@ func fetchChannelLogEntry(log *bbolt.Bucket,
|
|||||||
commitReader := bytes.NewReader(commitBytes)
|
commitReader := bytes.NewReader(commitBytes)
|
||||||
return deserializeChanCommit(commitReader)
|
return deserializeChanCommit(commitReader)
|
||||||
}
|
}
|
||||||
|
|
||||||
func wipeChannelLogEntries(log *bbolt.Bucket) error {
|
|
||||||
// TODO(roasbeef): comment
|
|
||||||
|
|
||||||
logCursor := log.Cursor()
|
|
||||||
for k, _ := logCursor.First(); k != nil; k, _ = logCursor.Next() {
|
|
||||||
if err := logCursor.Delete(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
@ -1061,6 +1061,9 @@ func (c *ChannelGraph) DisconnectBlockAtHeight(height uint32) ([]*ChannelEdgeInf
|
|||||||
|
|
||||||
// Scan from chanIDStart to chanIDEnd, deleting every
|
// Scan from chanIDStart to chanIDEnd, deleting every
|
||||||
// found edge.
|
// found edge.
|
||||||
|
// NOTE: we must delete the edges after the cursor loop, since
|
||||||
|
// modifying the bucket while traversing is not safe.
|
||||||
|
var keys [][]byte
|
||||||
cursor := edgeIndex.Cursor()
|
cursor := edgeIndex.Cursor()
|
||||||
for k, v := cursor.Seek(chanIDStart[:]); k != nil &&
|
for k, v := cursor.Seek(chanIDStart[:]); k != nil &&
|
||||||
bytes.Compare(k, chanIDEnd[:]) <= 0; k, v = cursor.Next() {
|
bytes.Compare(k, chanIDEnd[:]) <= 0; k, v = cursor.Next() {
|
||||||
@ -1070,6 +1073,12 @@ func (c *ChannelGraph) DisconnectBlockAtHeight(height uint32) ([]*ChannelEdgeInf
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
keys = append(keys, k)
|
||||||
|
removedChans = append(removedChans, &edgeInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, k := range keys {
|
||||||
err = delChannelEdge(
|
err = delChannelEdge(
|
||||||
edges, edgeIndex, chanIndex, zombieIndex, nodes,
|
edges, edgeIndex, chanIndex, zombieIndex, nodes,
|
||||||
k, false,
|
k, false,
|
||||||
@ -1077,8 +1086,6 @@ func (c *ChannelGraph) DisconnectBlockAtHeight(height uint32) ([]*ChannelEdgeInf
|
|||||||
if err != nil && err != ErrEdgeNotFound {
|
if err != nil && err != ErrEdgeNotFound {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
removedChans = append(removedChans, &edgeInfo)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete all the entries in the prune log having a height
|
// Delete all the entries in the prune log having a height
|
||||||
@ -1099,10 +1106,18 @@ func (c *ChannelGraph) DisconnectBlockAtHeight(height uint32) ([]*ChannelEdgeInf
|
|||||||
var pruneKeyEnd [4]byte
|
var pruneKeyEnd [4]byte
|
||||||
byteOrder.PutUint32(pruneKeyEnd[:], math.MaxUint32)
|
byteOrder.PutUint32(pruneKeyEnd[:], math.MaxUint32)
|
||||||
|
|
||||||
|
// To avoid modifying the bucket while traversing, we delete
|
||||||
|
// the keys in a second loop.
|
||||||
|
var pruneKeys [][]byte
|
||||||
pruneCursor := pruneBucket.Cursor()
|
pruneCursor := pruneBucket.Cursor()
|
||||||
for k, _ := pruneCursor.Seek(pruneKeyStart[:]); k != nil &&
|
for k, _ := pruneCursor.Seek(pruneKeyStart[:]); k != nil &&
|
||||||
bytes.Compare(k, pruneKeyEnd[:]) <= 0; k, _ = pruneCursor.Next() {
|
bytes.Compare(k, pruneKeyEnd[:]) <= 0; k, _ = pruneCursor.Next() {
|
||||||
if err := pruneCursor.Delete(); err != nil {
|
|
||||||
|
pruneKeys = append(pruneKeys, k)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, k := range pruneKeys {
|
||||||
|
if err := pruneBucket.Delete(k); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user