channeldb: further GC optimizations during path finding
In this commit, we made a series of modification to the way we handle reading edges and vertexes from disk, in order to reduce the amount of garbage generated: 1. Properly use PubKeyBytes are required rather than PubKey() 2. Return direct structs rather than pointers, and leave it to the runtime to perform escape analysis. 3. In-line the former readSig() method when reading sigs from disk.
This commit is contained in:
parent
03abc73e8d
commit
3e422fedd3
@ -210,7 +210,7 @@ func (c *ChannelGraph) ForEachChannel(cb func(*ChannelEdgeInfo, *ChannelEdgePoli
|
|||||||
// With both edges read, execute the call back. IF this
|
// With both edges read, execute the call back. IF this
|
||||||
// function returns an error then the transaction will
|
// function returns an error then the transaction will
|
||||||
// be aborted.
|
// be aborted.
|
||||||
return cb(edgeInfo, edge1, edge2)
|
return cb(&edgeInfo, edge1, edge2)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -253,7 +253,7 @@ func (c *ChannelGraph) ForEachNode(tx *bolt.Tx, cb func(*bolt.Tx, *LightningNode
|
|||||||
|
|
||||||
// Execute the callback, the transaction will abort if
|
// Execute the callback, the transaction will abort if
|
||||||
// this returns an error.
|
// this returns an error.
|
||||||
return cb(tx, node)
|
return cb(tx, &node)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,7 +294,7 @@ func (c *ChannelGraph) SourceNode() (*LightningNode, error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
source = node
|
source = &node
|
||||||
source.db = c.db
|
source.db = c.db
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@ -622,7 +622,7 @@ func (c *ChannelGraph) PruneGraph(spentOutputs []*wire.OutPoint,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
chansClosed = append(chansClosed, edgeInfo)
|
chansClosed = append(chansClosed, &edgeInfo)
|
||||||
|
|
||||||
// Attempt to delete the channel, an ErrEdgeNotFound
|
// Attempt to delete the channel, an ErrEdgeNotFound
|
||||||
// will be returned if that outpoint isn't known to be
|
// will be returned if that outpoint isn't known to be
|
||||||
@ -727,7 +727,7 @@ func (c *ChannelGraph) DisconnectBlockAtHeight(height uint32) ([]*ChannelEdgeInf
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
removedChans = append(removedChans, edgeInfo)
|
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
|
||||||
@ -1081,7 +1081,7 @@ func (c *ChannelGraph) FetchLightningNode(pub *btcec.PublicKey) (*LightningNode,
|
|||||||
}
|
}
|
||||||
n.db = c.db
|
n.db = c.db
|
||||||
|
|
||||||
node = n
|
node = &n
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@ -1153,11 +1153,7 @@ func (c *ChannelGraph) HasLightningNode(nodePub [33]byte) (time.Time, bool, erro
|
|||||||
func (l *LightningNode) ForEachChannel(tx *bolt.Tx,
|
func (l *LightningNode) ForEachChannel(tx *bolt.Tx,
|
||||||
cb func(*bolt.Tx, *ChannelEdgeInfo, *ChannelEdgePolicy, *ChannelEdgePolicy) error) error {
|
cb func(*bolt.Tx, *ChannelEdgeInfo, *ChannelEdgePolicy, *ChannelEdgePolicy) error) error {
|
||||||
|
|
||||||
pub, err := l.PubKey()
|
nodePub := l.PubKeyBytes[:]
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
nodePub := pub.SerializeCompressed()
|
|
||||||
|
|
||||||
traversal := func(tx *bolt.Tx) error {
|
traversal := func(tx *bolt.Tx) error {
|
||||||
nodes := tx.Bucket(nodeBucket)
|
nodes := tx.Bucket(nodeBucket)
|
||||||
@ -1210,12 +1206,7 @@ func (l *LightningNode) ForEachChannel(tx *bolt.Tx,
|
|||||||
|
|
||||||
// We'll also fetch the incoming edge so this
|
// We'll also fetch the incoming edge so this
|
||||||
// information can be available to the caller.
|
// information can be available to the caller.
|
||||||
incomingNodeKey, err := toEdgePolicy.Node.PubKey()
|
incomingNode := toEdgePolicy.Node.PubKeyBytes[:]
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
incomingNode := incomingNodeKey.SerializeCompressed()
|
|
||||||
|
|
||||||
fromEdgePolicy, err := fetchChanEdgePolicy(
|
fromEdgePolicy, err := fetchChanEdgePolicy(
|
||||||
edges, chanID, incomingNode, nodes,
|
edges, chanID, incomingNode, nodes,
|
||||||
)
|
)
|
||||||
@ -1231,7 +1222,7 @@ func (l *LightningNode) ForEachChannel(tx *bolt.Tx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Finally, we execute the callback.
|
// Finally, we execute the callback.
|
||||||
err = cb(tx, edgeInfo, toEdgePolicy, fromEdgePolicy)
|
err = cb(tx, &edgeInfo, toEdgePolicy, fromEdgePolicy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -1658,7 +1649,7 @@ func (c *ChannelGraph) FetchChannelEdgesByOutpoint(op *wire.OutPoint) (*ChannelE
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
edgeInfo = edge
|
edgeInfo = &edge
|
||||||
|
|
||||||
// Once we have the information about the channels' parameters,
|
// Once we have the information about the channels' parameters,
|
||||||
// we'll fetch the routing policies for each for the directed
|
// we'll fetch the routing policies for each for the directed
|
||||||
@ -1720,7 +1711,7 @@ func (c *ChannelGraph) FetchChannelEdgesByID(chanID uint64) (*ChannelEdgeInfo, *
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
edgeInfo = edge
|
edgeInfo = &edge
|
||||||
|
|
||||||
e1, e2, err := fetchChanEdgePolicies(edgeIndex, edges, nodes,
|
e1, e2, err := fetchChanEdgePolicies(edgeIndex, edges, nodes,
|
||||||
channelID[:], c.db)
|
channelID[:], c.db)
|
||||||
@ -1874,38 +1865,37 @@ func putLightningNode(nodeBucket *bolt.Bucket, aliasBucket *bolt.Bucket, node *L
|
|||||||
}
|
}
|
||||||
|
|
||||||
func fetchLightningNode(nodeBucket *bolt.Bucket,
|
func fetchLightningNode(nodeBucket *bolt.Bucket,
|
||||||
nodePub []byte) (*LightningNode, error) {
|
nodePub []byte) (LightningNode, error) {
|
||||||
|
|
||||||
nodeBytes := nodeBucket.Get(nodePub)
|
nodeBytes := nodeBucket.Get(nodePub)
|
||||||
if nodeBytes == nil {
|
if nodeBytes == nil {
|
||||||
return nil, ErrGraphNodeNotFound
|
return LightningNode{}, ErrGraphNodeNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeReader := bytes.NewReader(nodeBytes)
|
nodeReader := bytes.NewReader(nodeBytes)
|
||||||
return deserializeLightningNode(nodeReader)
|
return deserializeLightningNode(nodeReader)
|
||||||
}
|
}
|
||||||
|
|
||||||
func deserializeLightningNode(r io.Reader) (*LightningNode, error) {
|
func deserializeLightningNode(r io.Reader) (LightningNode, error) {
|
||||||
var (
|
var (
|
||||||
|
node LightningNode
|
||||||
scratch [8]byte
|
scratch [8]byte
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
node := &LightningNode{}
|
|
||||||
|
|
||||||
if _, err := r.Read(scratch[:]); err != nil {
|
if _, err := r.Read(scratch[:]); err != nil {
|
||||||
return nil, err
|
return LightningNode{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
unix := int64(byteOrder.Uint64(scratch[:]))
|
unix := int64(byteOrder.Uint64(scratch[:]))
|
||||||
node.LastUpdate = time.Unix(unix, 0)
|
node.LastUpdate = time.Unix(unix, 0)
|
||||||
|
|
||||||
if _, err := io.ReadFull(r, node.PubKeyBytes[:]); err != nil {
|
if _, err := io.ReadFull(r, node.PubKeyBytes[:]); err != nil {
|
||||||
return nil, err
|
return LightningNode{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := r.Read(scratch[:2]); err != nil {
|
if _, err := r.Read(scratch[:2]); err != nil {
|
||||||
return nil, err
|
return LightningNode{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
hasNodeAnn := byteOrder.Uint16(scratch[:2])
|
hasNodeAnn := byteOrder.Uint16(scratch[:2])
|
||||||
@ -1924,29 +1914,29 @@ func deserializeLightningNode(r io.Reader) (*LightningNode, error) {
|
|||||||
// We did get a node announcement for this node, so we'll have the rest
|
// We did get a node announcement for this node, so we'll have the rest
|
||||||
// of the data available.
|
// of the data available.
|
||||||
if err := binary.Read(r, byteOrder, &node.Color.R); err != nil {
|
if err := binary.Read(r, byteOrder, &node.Color.R); err != nil {
|
||||||
return nil, err
|
return LightningNode{}, err
|
||||||
}
|
}
|
||||||
if err := binary.Read(r, byteOrder, &node.Color.G); err != nil {
|
if err := binary.Read(r, byteOrder, &node.Color.G); err != nil {
|
||||||
return nil, err
|
return LightningNode{}, err
|
||||||
}
|
}
|
||||||
if err := binary.Read(r, byteOrder, &node.Color.B); err != nil {
|
if err := binary.Read(r, byteOrder, &node.Color.B); err != nil {
|
||||||
return nil, err
|
return LightningNode{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
node.Alias, err = wire.ReadVarString(r, 0)
|
node.Alias, err = wire.ReadVarString(r, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return LightningNode{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
fv := lnwire.NewFeatureVector(nil, lnwire.GlobalFeatures)
|
fv := lnwire.NewFeatureVector(nil, lnwire.GlobalFeatures)
|
||||||
err = fv.Decode(r)
|
err = fv.Decode(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return LightningNode{}, err
|
||||||
}
|
}
|
||||||
node.Features = fv
|
node.Features = fv
|
||||||
|
|
||||||
if _, err := r.Read(scratch[:2]); err != nil {
|
if _, err := r.Read(scratch[:2]); err != nil {
|
||||||
return nil, err
|
return LightningNode{}, err
|
||||||
}
|
}
|
||||||
numAddresses := int(byteOrder.Uint16(scratch[:2]))
|
numAddresses := int(byteOrder.Uint16(scratch[:2]))
|
||||||
|
|
||||||
@ -1954,7 +1944,7 @@ func deserializeLightningNode(r io.Reader) (*LightningNode, error) {
|
|||||||
for i := 0; i < numAddresses; i++ {
|
for i := 0; i < numAddresses; i++ {
|
||||||
address, err := deserializeAddr(r)
|
address, err := deserializeAddr(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return LightningNode{}, err
|
||||||
}
|
}
|
||||||
addresses = append(addresses, address)
|
addresses = append(addresses, address)
|
||||||
}
|
}
|
||||||
@ -1962,7 +1952,7 @@ func deserializeLightningNode(r io.Reader) (*LightningNode, error) {
|
|||||||
|
|
||||||
node.AuthSigBytes, err = wire.ReadVarBytes(r, 0, 80, "sig")
|
node.AuthSigBytes, err = wire.ReadVarBytes(r, 0, 80, "sig")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return LightningNode{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return node, nil
|
return node, nil
|
||||||
@ -2027,62 +2017,58 @@ func putChanEdgeInfo(edgeIndex *bolt.Bucket, edgeInfo *ChannelEdgeInfo, chanID [
|
|||||||
}
|
}
|
||||||
|
|
||||||
func fetchChanEdgeInfo(edgeIndex *bolt.Bucket,
|
func fetchChanEdgeInfo(edgeIndex *bolt.Bucket,
|
||||||
chanID []byte) (*ChannelEdgeInfo, error) {
|
chanID []byte) (ChannelEdgeInfo, error) {
|
||||||
|
|
||||||
edgeInfoBytes := edgeIndex.Get(chanID)
|
edgeInfoBytes := edgeIndex.Get(chanID)
|
||||||
if edgeInfoBytes == nil {
|
if edgeInfoBytes == nil {
|
||||||
return nil, ErrEdgeNotFound
|
return ChannelEdgeInfo{}, ErrEdgeNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
edgeInfoReader := bytes.NewReader(edgeInfoBytes)
|
edgeInfoReader := bytes.NewReader(edgeInfoBytes)
|
||||||
return deserializeChanEdgeInfo(edgeInfoReader)
|
return deserializeChanEdgeInfo(edgeInfoReader)
|
||||||
}
|
}
|
||||||
|
|
||||||
func deserializeChanEdgeInfo(r io.Reader) (*ChannelEdgeInfo, error) {
|
func deserializeChanEdgeInfo(r io.Reader) (ChannelEdgeInfo, error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
edgeInfo = &ChannelEdgeInfo{}
|
edgeInfo ChannelEdgeInfo
|
||||||
)
|
)
|
||||||
|
|
||||||
if _, err := io.ReadFull(r, edgeInfo.NodeKey1Bytes[:]); err != nil {
|
if _, err := io.ReadFull(r, edgeInfo.NodeKey1Bytes[:]); err != nil {
|
||||||
return nil, err
|
return ChannelEdgeInfo{}, err
|
||||||
}
|
}
|
||||||
if _, err := io.ReadFull(r, edgeInfo.NodeKey2Bytes[:]); err != nil {
|
if _, err := io.ReadFull(r, edgeInfo.NodeKey2Bytes[:]); err != nil {
|
||||||
return nil, err
|
return ChannelEdgeInfo{}, err
|
||||||
}
|
}
|
||||||
if _, err := io.ReadFull(r, edgeInfo.BitcoinKey1Bytes[:]); err != nil {
|
if _, err := io.ReadFull(r, edgeInfo.BitcoinKey1Bytes[:]); err != nil {
|
||||||
return nil, err
|
return ChannelEdgeInfo{}, err
|
||||||
}
|
}
|
||||||
if _, err := io.ReadFull(r, edgeInfo.BitcoinKey2Bytes[:]); err != nil {
|
if _, err := io.ReadFull(r, edgeInfo.BitcoinKey2Bytes[:]); err != nil {
|
||||||
return nil, err
|
return ChannelEdgeInfo{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
edgeInfo.Features, err = wire.ReadVarBytes(r, 0, 900, "features")
|
edgeInfo.Features, err = wire.ReadVarBytes(r, 0, 900, "features")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return ChannelEdgeInfo{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
proof := &ChannelAuthProof{}
|
proof := &ChannelAuthProof{}
|
||||||
|
|
||||||
readSig := func() ([]byte, error) {
|
proof.NodeSig1Bytes, err = wire.ReadVarBytes(r, 0, 80, "sigs")
|
||||||
return wire.ReadVarBytes(r, 0, 80, "sigs")
|
|
||||||
}
|
|
||||||
|
|
||||||
proof.NodeSig1Bytes, err = readSig()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return ChannelEdgeInfo{}, err
|
||||||
}
|
}
|
||||||
proof.NodeSig2Bytes, err = readSig()
|
proof.NodeSig2Bytes, err = wire.ReadVarBytes(r, 0, 80, "sigs")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return ChannelEdgeInfo{}, err
|
||||||
}
|
}
|
||||||
proof.BitcoinSig1Bytes, err = readSig()
|
proof.BitcoinSig1Bytes, err = wire.ReadVarBytes(r, 0, 80, "sigs")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return ChannelEdgeInfo{}, err
|
||||||
}
|
}
|
||||||
proof.BitcoinSig2Bytes, err = readSig()
|
proof.BitcoinSig2Bytes, err = wire.ReadVarBytes(r, 0, 80, "sigs")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return ChannelEdgeInfo{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !proof.IsEmpty() {
|
if !proof.IsEmpty() {
|
||||||
@ -2091,17 +2077,17 @@ func deserializeChanEdgeInfo(r io.Reader) (*ChannelEdgeInfo, error) {
|
|||||||
|
|
||||||
edgeInfo.ChannelPoint = wire.OutPoint{}
|
edgeInfo.ChannelPoint = wire.OutPoint{}
|
||||||
if err := readOutpoint(r, &edgeInfo.ChannelPoint); err != nil {
|
if err := readOutpoint(r, &edgeInfo.ChannelPoint); err != nil {
|
||||||
return nil, err
|
return ChannelEdgeInfo{}, err
|
||||||
}
|
}
|
||||||
if err := binary.Read(r, byteOrder, &edgeInfo.Capacity); err != nil {
|
if err := binary.Read(r, byteOrder, &edgeInfo.Capacity); err != nil {
|
||||||
return nil, err
|
return ChannelEdgeInfo{}, err
|
||||||
}
|
}
|
||||||
if err := binary.Read(r, byteOrder, &edgeInfo.ChannelID); err != nil {
|
if err := binary.Read(r, byteOrder, &edgeInfo.ChannelID); err != nil {
|
||||||
return nil, err
|
return ChannelEdgeInfo{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := io.ReadFull(r, edgeInfo.ChainHash[:]); err != nil {
|
if _, err := io.ReadFull(r, edgeInfo.ChainHash[:]); err != nil {
|
||||||
return nil, err
|
return ChannelEdgeInfo{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return edgeInfo, nil
|
return edgeInfo, nil
|
||||||
@ -2216,11 +2202,11 @@ func deserializeChanEdgePolicy(r io.Reader,
|
|||||||
|
|
||||||
edge := &ChannelEdgePolicy{}
|
edge := &ChannelEdgePolicy{}
|
||||||
|
|
||||||
sigBytes, err := wire.ReadVarBytes(r, 0, 80, "sig")
|
var err error
|
||||||
|
edge.SigBytes, err = wire.ReadVarBytes(r, 0, 80, "sig")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
edge.SigBytes = sigBytes
|
|
||||||
|
|
||||||
if err := binary.Read(r, byteOrder, &edge.ChannelID); err != nil {
|
if err := binary.Read(r, byteOrder, &edge.ChannelID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -2266,6 +2252,6 @@ func deserializeChanEdgePolicy(r io.Reader,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
edge.Node = node
|
edge.Node = &node
|
||||||
return edge, nil
|
return edge, nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user