channeldb/graph: properly determine old update timestamp for an edge

In this commit, we fix a lingering issue within the edge update index
where entries were not being properly pruned due to an incorrect
calculation of the offset of an edge's last update time. Since the
offset is being determined from the end to the start, we need to
subtract all the fields after an edge policy's last update time from the
total amount of bytes of the serialized edge policy to determine the
correct offset. This was also slightly off as the edge policy included
an extra byte, which has been fixed in the previous commit.

Instead of continuing the slicing approach however, we'll switch to
deserializing the raw bytes of an edge's policy to ensure this doesn't
happen in the future when/if the serialization methods change or extra
data is included.
This commit is contained in:
Wilmer Paulino committed 2018-09-04 18:33:38 -07:00
1 parent 492d581df6
commit 2f22e6c35f
1 file changed
+22 -13
+22 -13
View File
@@ -1617,14 +1617,18 @@ func (c *ChannelGraph) UpdateEdgePolicy(edge *ChannelEdgePolicy) error {
if err != nil { if err != nil {
return err return err
} }
nodes, err := tx.CreateBucketIfNotExists(nodeBucket)
if err != nil {
return err
}
return updateEdgePolicy(edges, edgeIndex, edge) return updateEdgePolicy(edges, edgeIndex, nodes, edge)
}) })
} }
// updateEdgePolicy attempts to update an edge's policy within the relevant // updateEdgePolicy attempts to update an edge's policy within the relevant
// buckets using an existing database transaction. // buckets using an existing database transaction.
func updateEdgePolicy(edges, edgeIndex *bolt.Bucket, func updateEdgePolicy(edges, edgeIndex, nodes *bolt.Bucket,
edge *ChannelEdgePolicy) error { edge *ChannelEdgePolicy) error {
// Create the channelID key be converting the channel ID // Create the channelID key be converting the channel ID
@@ -1652,7 +1656,7 @@ func updateEdgePolicy(edges, edgeIndex *bolt.Bucket,
// Finally, with the direction of the edge being updated // Finally, with the direction of the edge being updated
// identified, we update the on-disk edge representation. // identified, we update the on-disk edge representation.
return putChanEdgePolicy(edges, edge, fromNode, toNode) return putChanEdgePolicy(edges, nodes, edge, fromNode, toNode)
} }
// LightningNode represents an individual vertex/node within the channel graph. // LightningNode represents an individual vertex/node within the channel graph.
@@ -2949,7 +2953,9 @@ func deserializeChanEdgeInfo(r io.Reader) (ChannelEdgeInfo, error) {
return edgeInfo, nil return edgeInfo, nil
} }
func putChanEdgePolicy(edges *bolt.Bucket, edge *ChannelEdgePolicy, from, to []byte) error { func putChanEdgePolicy(edges, nodes *bolt.Bucket, edge *ChannelEdgePolicy,
from, to []byte) error {
var edgeKey [33 + 8]byte var edgeKey [33 + 8]byte
copy(edgeKey[:], from) copy(edgeKey[:], from)
byteOrder.PutUint64(edgeKey[33:], edge.ChannelID) byteOrder.PutUint64(edgeKey[33:], edge.ChannelID)
@@ -3012,17 +3018,20 @@ func putChanEdgePolicy(edges *bolt.Bucket, edge *ChannelEdgePolicy, from, to []b
// In order to delete the old entry, we'll need to obtain the // In order to delete the old entry, we'll need to obtain the
// *prior* update time in order to delete it. To do this, we'll // *prior* update time in order to delete it. To do this, we'll
// create an offset to slice in. Starting backwards, we'll // need to deserialize the existing policy within the database
// create an offset than puts us right after the flags // (now outdated by the new one), and delete its corresponding
// variable: // entry within the update index.
// oldEdgePolicy, err := deserializeChanEdgePolicy(
// * pubkeySize + fee+policySize + timelockSize + flagSize bytes.NewReader(edgeBytes), nodes,
updateEnd := 33 + (8 * 3) + 2 + 1 )
updateStart := updateEnd - 8 if err != nil {
oldUpdateTime := edgeBytes[updateStart:updateEnd] return err
}
oldUpdateTime := uint64(oldEdgePolicy.LastUpdate.Unix())
var oldIndexKey [8 + 8]byte var oldIndexKey [8 + 8]byte
copy(oldIndexKey[:], oldUpdateTime) byteOrder.PutUint64(oldIndexKey[:8], oldUpdateTime)
byteOrder.PutUint64(oldIndexKey[8:], edge.ChannelID) byteOrder.PutUint64(oldIndexKey[8:], edge.ChannelID)
if err := updateIndex.Delete(oldIndexKey[:]); err != nil { if err := updateIndex.Delete(oldIndexKey[:]); err != nil {