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 2018-08-31 14:59:35 -07:00
parent 492d581df6
commit 2f22e6c35f
No known key found for this signature in database
GPG Key ID: 6DF57B9F9514972F

@ -1617,14 +1617,18 @@ func (c *ChannelGraph) UpdateEdgePolicy(edge *ChannelEdgePolicy) error {
if err != nil {
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
// buckets using an existing database transaction.
func updateEdgePolicy(edges, edgeIndex *bolt.Bucket,
func updateEdgePolicy(edges, edgeIndex, nodes *bolt.Bucket,
edge *ChannelEdgePolicy) error {
// 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
// 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.
@ -2949,7 +2953,9 @@ func deserializeChanEdgeInfo(r io.Reader) (ChannelEdgeInfo, error) {
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
copy(edgeKey[:], from)
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
// *prior* update time in order to delete it. To do this, we'll
// create an offset to slice in. Starting backwards, we'll
// create an offset than puts us right after the flags
// variable:
//
// * pubkeySize + fee+policySize + timelockSize + flagSize
updateEnd := 33 + (8 * 3) + 2 + 1
updateStart := updateEnd - 8
oldUpdateTime := edgeBytes[updateStart:updateEnd]
// need to deserialize the existing policy within the database
// (now outdated by the new one), and delete its corresponding
// entry within the update index.
oldEdgePolicy, err := deserializeChanEdgePolicy(
bytes.NewReader(edgeBytes), nodes,
)
if err != nil {
return err
}
oldUpdateTime := uint64(oldEdgePolicy.LastUpdate.Unix())
var oldIndexKey [8 + 8]byte
copy(oldIndexKey[:], oldUpdateTime)
byteOrder.PutUint64(oldIndexKey[:8], oldUpdateTime)
byteOrder.PutUint64(oldIndexKey[8:], edge.ChannelID)
if err := updateIndex.Delete(oldIndexKey[:]); err != nil {