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)
// 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.
func (d dbNode) PubKey() *btcec.PublicKey {
pubKey, _ := d.node.PubKey()
return pubKey
func (d dbNode) PubKey() [33]byte {
return d.node.PubKeyBytes
}
// 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.
//
// NOTE: Part of the autopilot.Node interface.
func (m memNode) PubKey() *btcec.PublicKey {
return m.pub
func (m memNode) PubKey() [33]byte {
var n [33]byte
copy(n[:], m.pub.SerializeCompressed())
return n
}
// Addrs returns a slice of publicly reachable public TCP addresses that the

@ -17,8 +17,8 @@ import (
type Node interface {
// 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.
PubKey() *btcec.PublicKey
// agent. The key will be returned in serialized compressed format.
PubKey() [33]byte
// Addrs returns a slice of publicly reachable public TCP addresses
// that the peer is known to be listening on.

@ -1,6 +1,7 @@
package autopilot
import (
"bytes"
"fmt"
prand "math/rand"
"time"
@ -153,6 +154,8 @@ func (p *ConstrainedPrefAttachment) Select(self *btcec.PublicKey, g ChannelGraph
return directives, nil
}
selfPubBytes := self.SerializeCompressed()
// We'll continue our attachment loop until we've exhausted the current
// amount of available funds.
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?
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
// 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
// order to avoid attempting to make a channel with
// ourselves.
if node.PubKey().IsEqual(self) {
if bytes.Equal(nID[:], selfPubBytes) {
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
// 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{
// TODO(roasbeef): need curve?
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
// nodes to avoid attaching to it again.
visited[NewNodeID(selectedNode.PubKey())] = struct{}{}
visited[NodeID(pubBytes)] = struct{}{}
}
numSelectedNodes := int64(len(directives))

@ -1,6 +1,7 @@
package autopilot
import (
"bytes"
"io/ioutil"
"os"
"testing"
@ -344,11 +345,14 @@ func TestConstrainedPrefAttachmentSelectTwoVertexes(t *testing.T) {
// The node attached to should be amongst the two edges
// created above.
for _, directive := range directives {
edge1Pub := edge1.Peer.PubKey()
edge2Pub := edge2.Peer.PubKey()
switch {
case directive.PeerKey.IsEqual(edge1.Peer.PubKey()):
case directive.PeerKey.IsEqual(edge2.Peer.PubKey()):
case bytes.Equal(directive.PeerKey.SerializeCompressed(), edge1Pub[:]):
case bytes.Equal(directive.PeerKey.SerializeCompressed(), edge2Pub[:]):
default:
t1.Fatalf("attache to unknown node: %x",
t1.Fatalf("attached to unknown node: %x",
directive.PeerKey.SerializeCompressed())
}
@ -472,8 +476,15 @@ func TestConstrainedPrefAttachmentSelectGreedyAllocation(t *testing.T) {
if err != nil {
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(
edge1.Peer.PubKey(), nil, chanCapacity,
peerPub, nil, chanCapacity,
)
if err != nil {
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 {
nID := autopilot.NewNodeID(node.PubKey())
nID := autopilot.NodeID(node.PubKey())
if _, ok := c.tried[nID]; ok {
return nil
}
@ -187,8 +187,8 @@ func (c *ChannelGraphBootstrapper) SampleNodeAddrs(numAddrs uint32,
// value. When comparing, we skip the first byte as
// it's 50/50. If it isn't less, than then we'll
// continue forward.
nodePub := node.PubKey().SerializeCompressed()[1:]
if bytes.Compare(c.hashAccumulator[:], nodePub) > 0 {
nodePubKeyBytes := node.PubKey()
if bytes.Compare(c.hashAccumulator[:], nodePubKeyBytes[1:]) > 0 {
return nil
}
@ -205,11 +205,18 @@ func (c *ChannelGraphBootstrapper) SampleNodeAddrs(numAddrs uint32,
return nil
}
nodePub, err := btcec.ParsePubKey(
nodePubKeyBytes[:], btcec.S256(),
)
if err != nil {
return err
}
// At this point, we've found an eligible node,
// so we'll return early with our shibboleth
// error.
a = append(a, &lnwire.NetAddress{
IdentityKey: node.PubKey(),
IdentityKey: nodePub,
Address: nodeAddr,
})
}