Merge pull request #1811 from Roasbeef/autopilot-cpu-usage-fix

autopilot: modify the graph interface to return raw bytes for node pubkeys, not entire key
This commit is contained in:
Olaoluwa Osuntokun 2018-09-03 19:56:51 -07:00 committed by GitHub
commit 4f43c1c943
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 48 additions and 20 deletions

@ -59,12 +59,12 @@ type dbNode struct {
var _ Node = (*dbNode)(nil) var _ Node = (*dbNode)(nil)
// PubKey is the identity public key of the node. This will be used to attempt // PubKey is the identity public key of the node. This will be used to attempt
// to target a node for channel opening by the main autopilot agent. // to target a node for channel opening by the main autopilot agent. The key
// will be returned in serialized compressed format.
// //
// NOTE: Part of the autopilot.Node interface. // NOTE: Part of the autopilot.Node interface.
func (d dbNode) PubKey() *btcec.PublicKey { func (d dbNode) PubKey() [33]byte {
pubKey, _ := d.node.PubKey() return d.node.PubKeyBytes
return pubKey
} }
// Addrs returns a slice of publicly reachable public TCP addresses that the // Addrs returns a slice of publicly reachable public TCP addresses that the
@ -406,8 +406,11 @@ var _ Node = (*memNode)(nil)
// to target a node for channel opening by the main autopilot agent. // to target a node for channel opening by the main autopilot agent.
// //
// NOTE: Part of the autopilot.Node interface. // NOTE: Part of the autopilot.Node interface.
func (m memNode) PubKey() *btcec.PublicKey { func (m memNode) PubKey() [33]byte {
return m.pub var n [33]byte
copy(n[:], m.pub.SerializeCompressed())
return n
} }
// Addrs returns a slice of publicly reachable public TCP addresses that the // Addrs returns a slice of publicly reachable public TCP addresses that the

@ -17,8 +17,8 @@ import (
type Node interface { type Node interface {
// PubKey is the identity public key of the node. This will be used to // PubKey is the identity public key of the node. This will be used to
// attempt to target a node for channel opening by the main autopilot // attempt to target a node for channel opening by the main autopilot
// agent. // agent. The key will be returned in serialized compressed format.
PubKey() *btcec.PublicKey PubKey() [33]byte
// Addrs returns a slice of publicly reachable public TCP addresses // Addrs returns a slice of publicly reachable public TCP addresses
// that the peer is known to be listening on. // that the peer is known to be listening on.

@ -1,6 +1,7 @@
package autopilot package autopilot
import ( import (
"bytes"
"fmt" "fmt"
prand "math/rand" prand "math/rand"
"time" "time"
@ -153,6 +154,8 @@ func (p *ConstrainedPrefAttachment) Select(self *btcec.PublicKey, g ChannelGraph
return directives, nil return directives, nil
} }
selfPubBytes := self.SerializeCompressed()
// We'll continue our attachment loop until we've exhausted the current // We'll continue our attachment loop until we've exhausted the current
// amount of available funds. // amount of available funds.
visited := make(map[NodeID]struct{}) visited := make(map[NodeID]struct{})
@ -174,7 +177,7 @@ func (p *ConstrainedPrefAttachment) Select(self *btcec.PublicKey, g ChannelGraph
// //
// TODO(roasbeef): add noise to make adversarially resistant? // TODO(roasbeef): add noise to make adversarially resistant?
if err := g.ForEachNode(func(node Node) error { if err := g.ForEachNode(func(node Node) error {
nID := NewNodeID(node.PubKey()) nID := NodeID(node.PubKey())
// Once a node has already been attached to, we'll // Once a node has already been attached to, we'll
// ensure that it isn't factored into any further // ensure that it isn't factored into any further
@ -186,7 +189,7 @@ func (p *ConstrainedPrefAttachment) Select(self *btcec.PublicKey, g ChannelGraph
// If we come across ourselves, them we'll continue in // If we come across ourselves, them we'll continue in
// order to avoid attempting to make a channel with // order to avoid attempting to make a channel with
// ourselves. // ourselves.
if node.PubKey().IsEqual(self) { if bytes.Equal(nID[:], selfPubBytes) {
return nil return nil
} }
@ -235,7 +238,11 @@ func (p *ConstrainedPrefAttachment) Select(self *btcec.PublicKey, g ChannelGraph
// With the node selected, we'll add this (node, amount) tuple // With the node selected, we'll add this (node, amount) tuple
// to out set of recommended directives. // to out set of recommended directives.
pub := selectedNode.PubKey() pubBytes := selectedNode.PubKey()
pub, err := btcec.ParsePubKey(pubBytes[:], btcec.S256())
if err != nil {
return nil, err
}
directives = append(directives, AttachmentDirective{ directives = append(directives, AttachmentDirective{
// TODO(roasbeef): need curve? // TODO(roasbeef): need curve?
PeerKey: &btcec.PublicKey{ PeerKey: &btcec.PublicKey{
@ -247,7 +254,7 @@ func (p *ConstrainedPrefAttachment) Select(self *btcec.PublicKey, g ChannelGraph
// With the node selected, we'll add it to the set of visited // With the node selected, we'll add it to the set of visited
// nodes to avoid attaching to it again. // nodes to avoid attaching to it again.
visited[NewNodeID(selectedNode.PubKey())] = struct{}{} visited[NodeID(pubBytes)] = struct{}{}
} }
numSelectedNodes := int64(len(directives)) numSelectedNodes := int64(len(directives))

@ -1,6 +1,7 @@
package autopilot package autopilot
import ( import (
"bytes"
"io/ioutil" "io/ioutil"
"os" "os"
"testing" "testing"
@ -344,11 +345,14 @@ func TestConstrainedPrefAttachmentSelectTwoVertexes(t *testing.T) {
// The node attached to should be amongst the two edges // The node attached to should be amongst the two edges
// created above. // created above.
for _, directive := range directives { for _, directive := range directives {
edge1Pub := edge1.Peer.PubKey()
edge2Pub := edge2.Peer.PubKey()
switch { switch {
case directive.PeerKey.IsEqual(edge1.Peer.PubKey()): case bytes.Equal(directive.PeerKey.SerializeCompressed(), edge1Pub[:]):
case directive.PeerKey.IsEqual(edge2.Peer.PubKey()): case bytes.Equal(directive.PeerKey.SerializeCompressed(), edge2Pub[:]):
default: default:
t1.Fatalf("attache to unknown node: %x", t1.Fatalf("attached to unknown node: %x",
directive.PeerKey.SerializeCompressed()) directive.PeerKey.SerializeCompressed())
} }
@ -472,8 +476,15 @@ func TestConstrainedPrefAttachmentSelectGreedyAllocation(t *testing.T) {
if err != nil { if err != nil {
t1.Fatalf("unable to create channel: %v", err) t1.Fatalf("unable to create channel: %v", err)
} }
peerPubBytes := edge1.Peer.PubKey()
peerPub, err := btcec.ParsePubKey(
peerPubBytes[:], btcec.S256(),
)
if err != nil {
t.Fatalf("unable to parse pubkey: %v", err)
}
_, _, err = graph.addRandChannel( _, _, err = graph.addRandChannel(
edge1.Peer.PubKey(), nil, chanCapacity, peerPub, nil, chanCapacity,
) )
if err != nil { if err != nil {
t1.Fatalf("unable to create channel: %v", err) t1.Fatalf("unable to create channel: %v", err)

@ -177,7 +177,7 @@ func (c *ChannelGraphBootstrapper) SampleNodeAddrs(numAddrs uint32,
) )
err := c.chanGraph.ForEachNode(func(node autopilot.Node) error { err := c.chanGraph.ForEachNode(func(node autopilot.Node) error {
nID := autopilot.NewNodeID(node.PubKey()) nID := autopilot.NodeID(node.PubKey())
if _, ok := c.tried[nID]; ok { if _, ok := c.tried[nID]; ok {
return nil return nil
} }
@ -187,8 +187,8 @@ func (c *ChannelGraphBootstrapper) SampleNodeAddrs(numAddrs uint32,
// value. When comparing, we skip the first byte as // value. When comparing, we skip the first byte as
// it's 50/50. If it isn't less, than then we'll // it's 50/50. If it isn't less, than then we'll
// continue forward. // continue forward.
nodePub := node.PubKey().SerializeCompressed()[1:] nodePubKeyBytes := node.PubKey()
if bytes.Compare(c.hashAccumulator[:], nodePub) > 0 { if bytes.Compare(c.hashAccumulator[:], nodePubKeyBytes[1:]) > 0 {
return nil return nil
} }
@ -205,11 +205,18 @@ func (c *ChannelGraphBootstrapper) SampleNodeAddrs(numAddrs uint32,
return nil return nil
} }
nodePub, err := btcec.ParsePubKey(
nodePubKeyBytes[:], btcec.S256(),
)
if err != nil {
return err
}
// At this point, we've found an eligible node, // At this point, we've found an eligible node,
// so we'll return early with our shibboleth // so we'll return early with our shibboleth
// error. // error.
a = append(a, &lnwire.NetAddress{ a = append(a, &lnwire.NetAddress{
IdentityKey: node.PubKey(), IdentityKey: nodePub,
Address: nodeAddr, Address: nodeAddr,
}) })
} }