channeldb: add new methods to allow adding a new edge+policy w/ existing db transaction

This commit is contained in:
Olaoluwa Osuntokun 2018-12-09 19:30:26 -08:00
parent 11c6887ffa
commit c656788b0b
No known key found for this signature in database
GPG Key ID: CE58F7F8E20FD9A2
2 changed files with 107 additions and 105 deletions

@ -483,11 +483,18 @@ func (c *ChannelGraph) deleteLightningNode(nodes *bbolt.Bucket,
// the channel supports. The chanPoint and chanID are used to uniquely identify // the channel supports. The chanPoint and chanID are used to uniquely identify
// the edge globally within the database. // the edge globally within the database.
func (c *ChannelGraph) AddChannelEdge(edge *ChannelEdgeInfo) error { func (c *ChannelGraph) AddChannelEdge(edge *ChannelEdgeInfo) error {
return c.db.Update(func(tx *bbolt.Tx) error {
return c.addChannelEdge(tx, edge)
})
}
// addChannelEdge is the private form of AddChannelEdge that allows callers to
// utilize an existing db transaction.
func (c *ChannelGraph) addChannelEdge(tx *bbolt.Tx, edge *ChannelEdgeInfo) error {
// Construct the channel's primary key which is the 8-byte channel ID. // Construct the channel's primary key which is the 8-byte channel ID.
var chanKey [8]byte var chanKey [8]byte
binary.BigEndian.PutUint64(chanKey[:], edge.ChannelID) binary.BigEndian.PutUint64(chanKey[:], edge.ChannelID)
return c.db.Update(func(tx *bbolt.Tx) error {
nodes, err := tx.CreateBucketIfNotExists(nodeBucket) nodes, err := tx.CreateBucketIfNotExists(nodeBucket)
if err != nil { if err != nil {
return err return err
@ -505,18 +512,16 @@ func (c *ChannelGraph) AddChannelEdge(edge *ChannelEdgeInfo) error {
return err return err
} }
// First, attempt to check if this edge has already been // First, attempt to check if this edge has already been created. If
// created. If so, then we can exit early as this method is // so, then we can exit early as this method is meant to be idempotent.
// meant to be idempotent.
if edgeInfo := edgeIndex.Get(chanKey[:]); edgeInfo != nil { if edgeInfo := edgeIndex.Get(chanKey[:]); edgeInfo != nil {
return ErrEdgeAlreadyExist return ErrEdgeAlreadyExist
} }
// Before we insert the channel into the database, we'll ensure // Before we insert the channel into the database, we'll ensure that
// that both nodes already exist in the channel graph. If // both nodes already exist in the channel graph. If either node
// either node doesn't, then we'll insert a "shell" node that // doesn't, then we'll insert a "shell" node that just includes its
// just includes its public key, so subsequent validation and // public key, so subsequent validation and queries can work properly.
// queries can work properly.
_, node1Err := fetchLightningNode(nodes, edge.NodeKey1Bytes[:]) _, node1Err := fetchLightningNode(nodes, edge.NodeKey1Bytes[:])
switch { switch {
case node1Err == ErrGraphNodeNotFound: case node1Err == ErrGraphNodeNotFound:
@ -551,15 +556,15 @@ func (c *ChannelGraph) AddChannelEdge(edge *ChannelEdgeInfo) error {
return err return err
} }
// If the edge hasn't been created yet, then we'll first add it // If the edge hasn't been created yet, then we'll first add it to the
// to the edge index in order to associate the edge between two // edge index in order to associate the edge between two nodes and also
// nodes and also store the static components of the channel. // store the static components of the channel.
if err := putChanEdgeInfo(edgeIndex, edge, chanKey); err != nil { if err := putChanEdgeInfo(edgeIndex, edge, chanKey); err != nil {
return err return err
} }
// Mark edge policies for both sides as unknown. This is to // Mark edge policies for both sides as unknown. This is to enable
// enable efficient incoming channel lookup for a node. // efficient incoming channel lookup for a node.
for _, key := range []*[33]byte{&edge.NodeKey1Bytes, for _, key := range []*[33]byte{&edge.NodeKey1Bytes,
&edge.NodeKey2Bytes} { &edge.NodeKey2Bytes} {
@ -570,14 +575,13 @@ func (c *ChannelGraph) AddChannelEdge(edge *ChannelEdgeInfo) error {
} }
} }
// Finally we add it to the channel index which maps channel // Finally we add it to the channel index which maps channel points
// points (outpoints) to the shorter channel ID's. // (outpoints) to the shorter channel ID's.
var b bytes.Buffer var b bytes.Buffer
if err := writeOutpoint(&b, &edge.ChannelPoint); err != nil { if err := writeOutpoint(&b, &edge.ChannelPoint); err != nil {
return err return err
} }
return chanIndex.Put(b.Bytes(), chanKey[:]) return chanIndex.Put(b.Bytes(), chanKey[:])
})
} }
// HasChannelEdge returns true if the database knows of a channel edge with the // HasChannelEdge returns true if the database knows of a channel edge with the
@ -1639,11 +1643,18 @@ func delChannelByEdge(edges *bbolt.Bucket, edgeIndex *bbolt.Bucket,
// the nodes on either side of the channel. // the nodes on either side of the channel.
func (c *ChannelGraph) UpdateEdgePolicy(edge *ChannelEdgePolicy) error { func (c *ChannelGraph) UpdateEdgePolicy(edge *ChannelEdgePolicy) error {
return c.db.Update(func(tx *bbolt.Tx) error { return c.db.Update(func(tx *bbolt.Tx) error {
return updateEdgePolicy(tx, edge)
})
}
// updateEdgePolicy attempts to update an edge's policy within the relevant
// buckets using an existing database transaction.
func updateEdgePolicy(tx *bbolt.Tx, edge *ChannelEdgePolicy) error {
edges := tx.Bucket(edgeBucket) edges := tx.Bucket(edgeBucket)
if edges == nil { if edges == nil {
return ErrEdgeNotFound return ErrEdgeNotFound
}
}
edgeIndex := edges.Bucket(edgeIndexBucket) edgeIndex := edges.Bucket(edgeIndexBucket)
if edgeIndex == nil { if edgeIndex == nil {
return ErrEdgeNotFound return ErrEdgeNotFound
@ -1653,15 +1664,6 @@ func (c *ChannelGraph) UpdateEdgePolicy(edge *ChannelEdgePolicy) error {
return err return err
} }
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, nodes *bbolt.Bucket,
edge *ChannelEdgePolicy) error {
// Create the channelID key be converting the channel ID // Create the channelID key be converting the channel ID
// integer into a byte slice. // integer into a byte slice.
var chanID [8]byte var chanID [8]byte

@ -563,7 +563,7 @@ func migratePruneEdgeUpdateIndex(tx *bbolt.Tx) error {
return err return err
} }
err = updateEdgePolicy(edges, edgeIndex, nodes, edgePolicy) err = updateEdgePolicy(tx, edgePolicy)
if err != nil { if err != nil {
return err return err
} }