Skip to content

Commit

Permalink
temp: itest config refactor + bootstrapping test
Browse files Browse the repository at this point in the history
  • Loading branch information
ellemouton committed Nov 18, 2024
1 parent 8879a28 commit 6a1c0d4
Show file tree
Hide file tree
Showing 12 changed files with 423 additions and 132 deletions.
4 changes: 4 additions & 0 deletions itest/list_on_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -706,4 +706,8 @@ var allTestCases = []*lntest.TestCase{
Name: "remote graph",
TestFunc: testRemoteGraph,
},
{
Name: "remote graph peer bootstrap",
TestFunc: testRemoteGraphPeerBootstrap,
},
}
81 changes: 81 additions & 0 deletions itest/lnd_remote_graph_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package itest

import (
"context"
"fmt"
"time"

"github.com/btcsuite/btcd/btcutil"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lntest"
"github.com/lightningnetwork/lnd/lntest/node"
"github.com/lightningnetwork/lnd/lntest/port"
"github.com/lightningnetwork/lnd/lntest/wait"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -121,6 +125,83 @@ func testRemoteGraph(ht *lntest.HarnessTest) {
ht.CompletePaymentRequests(zane, []string{invoice.PaymentRequest})
}

func testRemoteGraphPeerBootstrap(ht *lntest.HarnessTest) {
// Set up a network. Set up a graph node that syncs the network.
// start zane in no-gossip node + remote graph + Allow peer bootstrap.
// show that it connects to peers that it got in graph node DB.

var (
//alice = ht.Alice

Check failure on line 134 in itest/lnd_remote_graph_test.go

View workflow job for this annotation

GitHub Actions / lint code

commentFormatting: put a space between `//` and comment text (gocritic)
bob = ht.Bob
)

// We derive an extra port for Carol, and we initialise her node with
// the port advertised as `--externalip` arguments.
ip2 := port.NextAvailablePort()

// Set up a network:
// A <- B <- C
carol := ht.NewNode("Carol", []string{fmt.Sprintf("--externalip=127.0.0.1:%d", ip2)})
carol.Cfg.P2PPort = ip2
ht.RestartNode(carol)

setupNetwork(ht, carol)

// Create graph provider node, Greg.
greg := ht.NewNode("Greg", nil)

// Now, connect G to B. Wait for it to sync gossip. It should know about
// the two public channels along with the public nodes and it should
// know Carol's advertised address.
ht.EnsureConnected(greg, bob)

err := wait.Predicate(func() bool {
info, err := greg.RPC.LN.GetNodeInfo(context.Background(), &lnrpc.NodeInfoRequest{
PubKey: carol.PubKeyStr,
})
require.NoError(ht.T, err)

return len(info.Node.Addresses) > 0
}, time.Second*5)
require.NoError(ht.T, err)

// Create a node, Zane, that uses Greg as its graph provider. Zane
// syncs no gossip.
zane := ht.NewNode("Zane", []string{
"--gossip.no-sync",
"--remotegraph.enable",
fmt.Sprintf(
"--remotegraph.rpchost=localhost:%d", greg.Cfg.RPCPort,
),
fmt.Sprintf(
"--remotegraph.tlscertpath=%s", greg.Cfg.TLSCertPath,
),
fmt.Sprintf(
"--remotegraph.macaroonpath=%s", greg.Cfg.AdminMacPath,
),
})

// Show that zane does not automatically connect to Carol via
// bootstrapping.
err = wait.Invariant(func() bool {
peerResp := zane.RPC.ListPeers()

return len(peerResp.Peers) == 0
}, time.Second*5)
require.NoError(ht.T, err)

// Now restart zane but this time allow peer bootstrap.
ht.RestartNode(zane, node.WithoutArg("nobootstrap"))

// Show that zane now does connect to Carol via bootstrapping.
err = wait.Predicate(func() bool {
peerResp := zane.RPC.ListPeers()

return len(peerResp.Peers) > 0
}, time.Second*5)
require.NoError(ht.T, err)
}

func setupNetwork(ht *lntest.HarnessTest, carol *node.HarnessNode) {
const chanAmt = btcutil.Amount(100000)
var networkChans []*lnrpc.ChannelPoint
Expand Down
54 changes: 51 additions & 3 deletions lnrpc/graphrpc/graph_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package graphrpc
import (
"context"
"encoding/hex"
"fmt"
"image/color"
"net"
"strconv"
"time"

"github.com/btcsuite/btcd/btcec/v2"
Expand All @@ -15,6 +17,7 @@ import (
graphdb "github.com/lightningnetwork/lnd/graph/db"
"github.com/lightningnetwork/lnd/graph/db/models"
"github.com/lightningnetwork/lnd/graph/session"
"github.com/lightningnetwork/lnd/lncfg"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/routing/route"
Expand Down Expand Up @@ -626,23 +629,68 @@ func (r *bootstrapper) SampleNodeAddrs(ctx context.Context, numAddrs uint32,
}

for _, addr := range addrs.Addresses {
netAddr, err := r.net.ResolveTCPAddr(
addr.Network, addr.Addr,
_, parsedHost, err := lncfg.ParseLNAddressPubkey(
addr.Addr,
)
if err != nil {
return nil, err
}

parsedAddr, err := parseAddr(parsedHost, r.net)
if err != nil {
return nil, fmt.Errorf("unable to parse peer "+
"address provided as a config option: "+
"%v", err)
}

netAddrs = append(netAddrs, &lnwire.NetAddress{
IdentityKey: nodeID,
Address: netAddr,
Address: parsedAddr,
})
}
}

return netAddrs, nil
}

const defaultPeerPort = 9735

// parseAddr parses an address from its string format to a net.Addr.
func parseAddr(address string, netCfg tor.Net) (net.Addr, error) {
var (
host string
port int
)

// Split the address into its host and port components.
h, p, err := net.SplitHostPort(address)
if err != nil {
// If a port wasn't specified, we'll assume the address only
// contains the host so we'll use the default port.
host = address
port = defaultPeerPort
} else {
// Otherwise, we'll note both the host and ports.
host = h
portNum, err := strconv.Atoi(p)
if err != nil {
return nil, err
}
port = portNum
}

if tor.IsOnionHost(host) {
return &tor.OnionAddr{OnionService: host, Port: port}, nil
}

// If the host is part of a TCP address, we'll use the network
// specific ResolveTCPAddr function in order to resolve these
// addresses over Tor in order to prevent leaking your real IP
// address.
hostPort := net.JoinHostPort(host, strconv.Itoa(port))
return netCfg.ResolveTCPAddr("tcp", hostPort)
}

// Name returns the name of the network peer bootstrapper implementation used
// by the remote node.
//
Expand Down
4 changes: 2 additions & 2 deletions lnrpc/graphrpc/graph_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,11 @@ func TestGraphClient(t *testing.T) {
Addresses: []*lnrpc.NodeAddress{
{
Network: "tcp",
Addr: "localhost:34",
Addr: fmt.Sprintf("%v@localhost:34", node1Hex),
},
{
Network: "tcp4",
Addr: "197.0.0.1:5",
Addr: fmt.Sprintf("%v@197.0.0.1:5", node1Hex),
},
},
},
Expand Down
4 changes: 2 additions & 2 deletions lnrpc/graphrpc/graph_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ var (
Entity: "graph",
Action: "read",
}},
"/graphrpc.Graph/BoostrapperName": {{
"/graphrpc.Graph/BootstrapperName": {{
Entity: "graph",
Action: "read",
}},
Expand Down Expand Up @@ -76,7 +76,7 @@ var _ GraphServer = (*Server)(nil)
// we'll create them on start up. If we're unable to locate, or create the
// macaroons we need, then we'll return with an error.
func New(cfg *Config) (*Server, lnrpc.MacaroonPerms, error) {
chanGraph := autopilot.ChannelGraphFromCachedDatabase(cfg.GraphDB)
chanGraph := autopilot.ChannelGraphFromDatabase(cfg.GraphDB)

bootstrapper, err := discovery.NewGraphBootstrapper(chanGraph)
if err != nil {
Expand Down
27 changes: 12 additions & 15 deletions lntest/bitcoind_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,21 @@ var _ node.BackendConfig = (*BitcoindBackendConfig)(nil)

// GenArgs returns the arguments needed to be passed to LND at startup for
// using this node as a chain backend.
func (b BitcoindBackendConfig) GenArgs() []string {
var args []string
args = append(args, "--bitcoin.node=bitcoind")
args = append(args, fmt.Sprintf("--bitcoind.rpchost=%v", b.rpcHost))
args = append(args, fmt.Sprintf("--bitcoind.rpcuser=%v", b.rpcUser))
args = append(args, fmt.Sprintf("--bitcoind.rpcpass=%v", b.rpcPass))
func (b BitcoindBackendConfig) GenArgs() map[string]string {
args := map[string]string{
"bitcoin.node": "bitcoind",
"bitcoind.rpchost": fmt.Sprintf("%v", b.rpcHost),
"bitcoind.rpcuser": fmt.Sprintf("%v", b.rpcUser),
"bitcoind.rpcpass": fmt.Sprintf("%v", b.rpcPass),
}

if b.rpcPolling {
args = append(args, fmt.Sprintf("--bitcoind.rpcpolling"))
args = append(args,
fmt.Sprintf("--bitcoind.blockpollinginterval=10ms"))
args = append(args,
fmt.Sprintf("--bitcoind.txpollinginterval=10ms"))
args["bitcoind.rpcpolling"] = ""
args["bitcoind.blockpollinginterval"] = "10ms"
args["bitcoind.txpollinginterval"] = "10ms"
} else {
args = append(args, fmt.Sprintf("--bitcoind.zmqpubrawblock=%v",
b.zmqBlockPath))
args = append(args, fmt.Sprintf("--bitcoind.zmqpubrawtx=%v",
b.zmqTxPath))
args["bitcoind.zmqpubrawblock"] = b.zmqBlockPath
args["bitcoind.zmqpubrawtx"] = b.zmqTxPath
}

return args
Expand Down
16 changes: 8 additions & 8 deletions lntest/btcd.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,16 @@ var _ node.BackendConfig = (*BtcdBackendConfig)(nil)

// GenArgs returns the arguments needed to be passed to LND at startup for
// using this node as a chain backend.
func (b BtcdBackendConfig) GenArgs() []string {
var args []string
func (b BtcdBackendConfig) GenArgs() map[string]string {
encodedCert := hex.EncodeToString(b.rpcConfig.Certificates)
args = append(args, "--bitcoin.node=btcd")
args = append(args, fmt.Sprintf("--btcd.rpchost=%v", b.rpcConfig.Host))
args = append(args, fmt.Sprintf("--btcd.rpcuser=%v", b.rpcConfig.User))
args = append(args, fmt.Sprintf("--btcd.rpcpass=%v", b.rpcConfig.Pass))
args = append(args, fmt.Sprintf("--btcd.rawrpccert=%v", encodedCert))

return args
return map[string]string{
"bitcoin.node": "btcd",
"btcd.rpchost": b.rpcConfig.Host,
"btcd.rpcuser": b.rpcConfig.User,
"btcd.rpcpass": b.rpcConfig.Pass,
"btcd.rawrpccert": encodedCert,
}
}

// ConnectMiner is called to establish a connection to the test miner.
Expand Down
Loading

0 comments on commit 6a1c0d4

Please sign in to comment.