Merge pull request #9248 from yyforyongyu/fix-itest
lntest: fix edge assertion and reset min relay fee
This commit is contained in:
13 files changed
+302
-128
No files matched your search
@@ -42,25 +42,23 @@ import (
|
|||||||
// thus a following operation will fail if it relies on the channel being
|
// thus a following operation will fail if it relies on the channel being
|
||||||
// enabled.
|
// enabled.
|
||||||
func testUpdateChanStatus(ht *lntest.HarnessTest) {
|
func testUpdateChanStatus(ht *lntest.HarnessTest) {
|
||||||
// Create two fresh nodes and open a channel between them.
|
// Prepare params.
|
||||||
alice, bob := ht.Alice, ht.Bob
|
chanAmt := btcutil.Amount(100_000)
|
||||||
args := []string{
|
openChannelParams := lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
}
|
||||||
|
cfg := []string{
|
||||||
"--minbackoff=60s",
|
"--minbackoff=60s",
|
||||||
"--chan-enable-timeout=3s",
|
"--chan-enable-timeout=3s",
|
||||||
"--chan-disable-timeout=6s",
|
"--chan-disable-timeout=6s",
|
||||||
"--chan-status-sample-interval=0.5s",
|
"--chan-status-sample-interval=0.5s",
|
||||||
}
|
}
|
||||||
ht.RestartNodeWithExtraArgs(alice, args)
|
cfgs := [][]string{cfg, cfg}
|
||||||
ht.RestartNodeWithExtraArgs(bob, args)
|
|
||||||
ht.EnsureConnected(alice, bob)
|
|
||||||
|
|
||||||
// Open a channel with 100k satoshis between Alice and Bob with Alice
|
// Create two fresh nodes and open a channel between them.
|
||||||
// being the sole funder of the channel.
|
chanPoints, nodes := ht.CreateSimpleNetwork(cfgs, openChannelParams)
|
||||||
chanAmt := btcutil.Amount(100000)
|
chanPoint := chanPoints[0]
|
||||||
chanPoint := ht.OpenChannel(
|
alice, bob := nodes[0], nodes[1]
|
||||||
alice, bob, lntest.OpenChannelParams{Amt: chanAmt},
|
|
||||||
)
|
|
||||||
defer ht.CloseChannel(alice, chanPoint)
|
|
||||||
|
|
||||||
// assertEdgeDisabled ensures that Alice has the correct Disabled state
|
// assertEdgeDisabled ensures that Alice has the correct Disabled state
|
||||||
// for given channel from her DescribeGraph.
|
// for given channel from her DescribeGraph.
|
||||||
@@ -237,17 +235,17 @@ func testUnannouncedChannels(ht *lntest.HarnessTest) {
|
|||||||
fundingChanPoint := ht.WaitForChannelOpenEvent(chanOpenUpdate)
|
fundingChanPoint := ht.WaitForChannelOpenEvent(chanOpenUpdate)
|
||||||
|
|
||||||
// Alice should have 1 edge in her graph.
|
// Alice should have 1 edge in her graph.
|
||||||
ht.AssertNumEdges(alice, 1, true)
|
ht.AssertNumActiveEdges(alice, 1, true)
|
||||||
|
|
||||||
// Channels should not be announced yet, hence Alice should have no
|
// Channels should not be announced yet, hence Alice should have no
|
||||||
// announced edges in her graph.
|
// announced edges in her graph.
|
||||||
ht.AssertNumEdges(alice, 0, false)
|
ht.AssertNumActiveEdges(alice, 0, false)
|
||||||
|
|
||||||
// Mine 4 more blocks, and check that the channel is now announced.
|
// Mine 4 more blocks, and check that the channel is now announced.
|
||||||
ht.MineBlocks(4)
|
ht.MineBlocks(4)
|
||||||
|
|
||||||
// Give the network a chance to learn that auth proof is confirmed.
|
// Give the network a chance to learn that auth proof is confirmed.
|
||||||
ht.AssertNumEdges(alice, 1, false)
|
ht.AssertNumActiveEdges(alice, 1, false)
|
||||||
|
|
||||||
// Close the channel used during the test.
|
// Close the channel used during the test.
|
||||||
ht.CloseChannel(alice, fundingChanPoint)
|
ht.CloseChannel(alice, fundingChanPoint)
|
||||||
|
|||||||
@@ -1421,9 +1421,10 @@ func testSendSelectedCoinsChannelReserve(ht *lntest.HarnessTest) {
|
|||||||
// Create a two-hop network: Alice -> Bob.
|
// Create a two-hop network: Alice -> Bob.
|
||||||
//
|
//
|
||||||
// NOTE: Alice will have one UTXO after the funding.
|
// NOTE: Alice will have one UTXO after the funding.
|
||||||
_, nodes := createSimpleNetwork(
|
cfg := []string{"--protocol.anchors"}
|
||||||
ht, []string{"--protocol.anchors"}, 2,
|
cfgs := [][]string{cfg, cfg}
|
||||||
lntest.OpenChannelParams{
|
_, nodes := ht.CreateSimpleNetwork(
|
||||||
|
cfgs, lntest.OpenChannelParams{
|
||||||
Amt: chanAmt,
|
Amt: chanAmt,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ func (m *mppTestScenario) openChannels(r *mppOpenChannelRequest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Each node should have exactly 6 edges.
|
// Each node should have exactly 6 edges.
|
||||||
m.ht.AssertNumEdges(hn, len(m.channelPoints), false)
|
m.ht.AssertNumActiveEdges(hn, len(m.channelPoints), false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ func testOpenChannelAfterReorg(ht *lntest.HarnessTest) {
|
|||||||
ht.AssertTopologyChannelOpen(bob, chanPoint)
|
ht.AssertTopologyChannelOpen(bob, chanPoint)
|
||||||
|
|
||||||
// Alice should now have 1 edge in her graph.
|
// Alice should now have 1 edge in her graph.
|
||||||
ht.AssertNumEdges(alice, 1, true)
|
ht.AssertNumActiveEdges(alice, 1, true)
|
||||||
|
|
||||||
// Now we disconnect Alice's chain backend from the original miner, and
|
// Now we disconnect Alice's chain backend from the original miner, and
|
||||||
// connect the two miners together. Since the temporary miner knows
|
// connect the two miners together. Since the temporary miner knows
|
||||||
@@ -112,7 +112,7 @@ func testOpenChannelAfterReorg(ht *lntest.HarnessTest) {
|
|||||||
|
|
||||||
// Since the fundingtx was reorged out, Alice should now have no edges
|
// Since the fundingtx was reorged out, Alice should now have no edges
|
||||||
// in her graph.
|
// in her graph.
|
||||||
ht.AssertNumEdges(alice, 0, true)
|
ht.AssertNumActiveEdges(alice, 0, true)
|
||||||
|
|
||||||
// Cleanup by mining the funding tx again, then closing the channel.
|
// Cleanup by mining the funding tx again, then closing the channel.
|
||||||
block = ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
block = ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||||
|
|||||||
@@ -41,9 +41,10 @@ func testPaymentSucceededHTLCRemoteSwept(ht *lntest.HarnessTest) {
|
|||||||
openChannelParams := lntest.OpenChannelParams{
|
openChannelParams := lntest.OpenChannelParams{
|
||||||
Amt: chanAmt,
|
Amt: chanAmt,
|
||||||
}
|
}
|
||||||
|
cfgs := [][]string{nil, nil}
|
||||||
|
|
||||||
// Create a two hop network: Alice -> Bob.
|
// Create a two hop network: Alice -> Bob.
|
||||||
chanPoints, nodes := createSimpleNetwork(ht, nil, 2, openChannelParams)
|
chanPoints, nodes := ht.CreateSimpleNetwork(cfgs, openChannelParams)
|
||||||
chanPoint := chanPoints[0]
|
chanPoint := chanPoints[0]
|
||||||
alice, bob := nodes[0], nodes[1]
|
alice, bob := nodes[0], nodes[1]
|
||||||
|
|
||||||
@@ -197,9 +198,10 @@ func runTestPaymentHTLCTimeout(ht *lntest.HarnessTest, restartAlice bool) {
|
|||||||
openChannelParams := lntest.OpenChannelParams{
|
openChannelParams := lntest.OpenChannelParams{
|
||||||
Amt: chanAmt,
|
Amt: chanAmt,
|
||||||
}
|
}
|
||||||
|
cfgs := [][]string{nil, nil}
|
||||||
|
|
||||||
// Create a two hop network: Alice -> Bob.
|
// Create a two hop network: Alice -> Bob.
|
||||||
chanPoints, nodes := createSimpleNetwork(ht, nil, 2, openChannelParams)
|
chanPoints, nodes := ht.CreateSimpleNetwork(cfgs, openChannelParams)
|
||||||
chanPoint := chanPoints[0]
|
chanPoint := chanPoints[0]
|
||||||
alice, bob := nodes[0], nodes[1]
|
alice, bob := nodes[0], nodes[1]
|
||||||
|
|
||||||
@@ -1247,9 +1249,10 @@ func runSendToRouteFailHTLCTimeout(ht *lntest.HarnessTest, restartAlice bool) {
|
|||||||
openChannelParams := lntest.OpenChannelParams{
|
openChannelParams := lntest.OpenChannelParams{
|
||||||
Amt: chanAmt,
|
Amt: chanAmt,
|
||||||
}
|
}
|
||||||
|
cfgs := [][]string{nil, nil}
|
||||||
|
|
||||||
// Create a two hop network: Alice -> Bob.
|
// Create a two hop network: Alice -> Bob.
|
||||||
chanPoints, nodes := createSimpleNetwork(ht, nil, 2, openChannelParams)
|
chanPoints, nodes := ht.CreateSimpleNetwork(cfgs, openChannelParams)
|
||||||
chanPoint := chanPoints[0]
|
chanPoint := chanPoints[0]
|
||||||
alice, bob := nodes[0], nodes[1]
|
alice, bob := nodes[0], nodes[1]
|
||||||
|
|
||||||
|
|||||||
@@ -985,7 +985,7 @@ func testMPPToSingleBlindedPath(ht *lntest.HarnessTest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Each node should have exactly numPublic edges.
|
// Each node should have exactly numPublic edges.
|
||||||
ht.AssertNumEdges(hn, numPublic, false)
|
ht.AssertNumActiveEdges(hn, numPublic, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make Dave create an invoice with a blinded path for Alice to pay.
|
// Make Dave create an invoice with a blinded path for Alice to pay.
|
||||||
@@ -1156,7 +1156,7 @@ func testBlindedRouteDummyHops(ht *lntest.HarnessTest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Each node should have exactly 5 edges.
|
// Each node should have exactly 5 edges.
|
||||||
ht.AssertNumEdges(hn, len(channelPoints), false)
|
ht.AssertNumActiveEdges(hn, len(channelPoints), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make Dave create an invoice with a blinded path for Alice to pay.
|
// Make Dave create an invoice with a blinded path for Alice to pay.
|
||||||
@@ -1325,7 +1325,7 @@ func testMPPToMultipleBlindedPaths(ht *lntest.HarnessTest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Each node should have exactly 5 edges.
|
// Each node should have exactly 5 edges.
|
||||||
ht.AssertNumEdges(hn, len(channelPoints), false)
|
ht.AssertNumActiveEdges(hn, len(channelPoints), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ok now make a payment that must be split to succeed.
|
// Ok now make a payment that must be split to succeed.
|
||||||
|
|||||||
@@ -591,12 +591,12 @@ func testPrivateChannels(ht *lntest.HarnessTest) {
|
|||||||
|
|
||||||
// Carol and Alice should know about 4, while Bob and Dave should only
|
// Carol and Alice should know about 4, while Bob and Dave should only
|
||||||
// know about 3, since one channel is private.
|
// know about 3, since one channel is private.
|
||||||
ht.AssertNumEdges(alice, 4, true)
|
ht.AssertNumActiveEdges(alice, 4, true)
|
||||||
ht.AssertNumEdges(alice, 3, false)
|
ht.AssertNumActiveEdges(alice, 3, false)
|
||||||
ht.AssertNumEdges(bob, 3, true)
|
ht.AssertNumActiveEdges(bob, 3, true)
|
||||||
ht.AssertNumEdges(carol, 4, true)
|
ht.AssertNumActiveEdges(carol, 4, true)
|
||||||
ht.AssertNumEdges(carol, 3, false)
|
ht.AssertNumActiveEdges(carol, 3, false)
|
||||||
ht.AssertNumEdges(dave, 3, true)
|
ht.AssertNumActiveEdges(dave, 3, true)
|
||||||
|
|
||||||
// Close all channels.
|
// Close all channels.
|
||||||
ht.CloseChannel(alice, chanPointAlice)
|
ht.CloseChannel(alice, chanPointAlice)
|
||||||
@@ -1525,8 +1525,9 @@ func testRouteFeeCutoff(ht *lntest.HarnessTest) {
|
|||||||
func testFeeLimitAfterQueryRoutes(ht *lntest.HarnessTest) {
|
func testFeeLimitAfterQueryRoutes(ht *lntest.HarnessTest) {
|
||||||
// Create a three hop network: Alice -> Bob -> Carol.
|
// Create a three hop network: Alice -> Bob -> Carol.
|
||||||
chanAmt := btcutil.Amount(100000)
|
chanAmt := btcutil.Amount(100000)
|
||||||
chanPoints, nodes := createSimpleNetwork(
|
cfgs := [][]string{nil, nil, nil}
|
||||||
ht, []string{}, 3, lntest.OpenChannelParams{Amt: chanAmt},
|
chanPoints, nodes := ht.CreateSimpleNetwork(
|
||||||
|
cfgs, lntest.OpenChannelParams{Amt: chanAmt},
|
||||||
)
|
)
|
||||||
alice, bob, carol := nodes[0], nodes[1], nodes[2]
|
alice, bob, carol := nodes[0], nodes[1], nodes[2]
|
||||||
chanPointAliceBob, chanPointBobCarol := chanPoints[0], chanPoints[1]
|
chanPointAliceBob, chanPointBobCarol := chanPoints[0], chanPoints[1]
|
||||||
|
|||||||
+14
-66
@@ -98,12 +98,14 @@ func testSweepCPFPAnchorOutgoingTimeout(ht *lntest.HarnessTest) {
|
|||||||
// swept so we can focus on testing HTLCs.
|
// swept so we can focus on testing HTLCs.
|
||||||
fmt.Sprintf("--bitcoin.defaultremotedelay=%v", cltvDelta*10),
|
fmt.Sprintf("--bitcoin.defaultremotedelay=%v", cltvDelta*10),
|
||||||
}
|
}
|
||||||
|
cfgs := [][]string{cfg, cfg, cfg}
|
||||||
|
|
||||||
openChannelParams := lntest.OpenChannelParams{
|
openChannelParams := lntest.OpenChannelParams{
|
||||||
Amt: invoiceAmt * 10,
|
Amt: invoiceAmt * 10,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a three hop network: Alice -> Bob -> Carol.
|
// Create a three hop network: Alice -> Bob -> Carol.
|
||||||
chanPoints, nodes := createSimpleNetwork(ht, cfg, 3, openChannelParams)
|
chanPoints, nodes := ht.CreateSimpleNetwork(cfgs, openChannelParams)
|
||||||
|
|
||||||
// Unwrap the results.
|
// Unwrap the results.
|
||||||
abChanPoint, bcChanPoint := chanPoints[0], chanPoints[1]
|
abChanPoint, bcChanPoint := chanPoints[0], chanPoints[1]
|
||||||
@@ -426,12 +428,14 @@ func testSweepCPFPAnchorIncomingTimeout(ht *lntest.HarnessTest) {
|
|||||||
// swept so we can focus on testing HTLCs.
|
// swept so we can focus on testing HTLCs.
|
||||||
fmt.Sprintf("--bitcoin.defaultremotedelay=%v", cltvDelta*10),
|
fmt.Sprintf("--bitcoin.defaultremotedelay=%v", cltvDelta*10),
|
||||||
}
|
}
|
||||||
|
cfgs := [][]string{cfg, cfg, cfg}
|
||||||
|
|
||||||
openChannelParams := lntest.OpenChannelParams{
|
openChannelParams := lntest.OpenChannelParams{
|
||||||
Amt: invoiceAmt * 10,
|
Amt: invoiceAmt * 10,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a three hop network: Alice -> Bob -> Carol.
|
// Create a three hop network: Alice -> Bob -> Carol.
|
||||||
chanPoints, nodes := createSimpleNetwork(ht, cfg, 3, openChannelParams)
|
chanPoints, nodes := ht.CreateSimpleNetwork(cfgs, openChannelParams)
|
||||||
|
|
||||||
// Unwrap the results.
|
// Unwrap the results.
|
||||||
abChanPoint, bcChanPoint := chanPoints[0], chanPoints[1]
|
abChanPoint, bcChanPoint := chanPoints[0], chanPoints[1]
|
||||||
@@ -771,12 +775,14 @@ func testSweepHTLCs(ht *lntest.HarnessTest) {
|
|||||||
// swept so we can focus on testing HTLCs.
|
// swept so we can focus on testing HTLCs.
|
||||||
fmt.Sprintf("--bitcoin.defaultremotedelay=%v", cltvDelta*10),
|
fmt.Sprintf("--bitcoin.defaultremotedelay=%v", cltvDelta*10),
|
||||||
}
|
}
|
||||||
|
cfgs := [][]string{cfg, cfg, cfg}
|
||||||
|
|
||||||
openChannelParams := lntest.OpenChannelParams{
|
openChannelParams := lntest.OpenChannelParams{
|
||||||
Amt: invoiceAmt * 10,
|
Amt: invoiceAmt * 10,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a three hop network: Alice -> Bob -> Carol.
|
// Create a three hop network: Alice -> Bob -> Carol.
|
||||||
chanPoints, nodes := createSimpleNetwork(ht, cfg, 3, openChannelParams)
|
chanPoints, nodes := ht.CreateSimpleNetwork(cfgs, openChannelParams)
|
||||||
|
|
||||||
// Unwrap the results.
|
// Unwrap the results.
|
||||||
abChanPoint, bcChanPoint := chanPoints[0], chanPoints[1]
|
abChanPoint, bcChanPoint := chanPoints[0], chanPoints[1]
|
||||||
@@ -1298,13 +1304,15 @@ func testSweepCommitOutputAndAnchor(ht *lntest.HarnessTest) {
|
|||||||
fmt.Sprintf("--sweeper.nodeadlineconftarget=%v", deadline),
|
fmt.Sprintf("--sweeper.nodeadlineconftarget=%v", deadline),
|
||||||
fmt.Sprintf("--bitcoin.defaultremotedelay=%v", toLocalCSV),
|
fmt.Sprintf("--bitcoin.defaultremotedelay=%v", toLocalCSV),
|
||||||
}
|
}
|
||||||
|
cfgs := [][]string{cfg, cfg}
|
||||||
|
|
||||||
openChannelParams := lntest.OpenChannelParams{
|
openChannelParams := lntest.OpenChannelParams{
|
||||||
Amt: fundAmt,
|
Amt: fundAmt,
|
||||||
PushAmt: bobBalance,
|
PushAmt: bobBalance,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a two hop network: Alice -> Bob.
|
// Create a two hop network: Alice -> Bob.
|
||||||
chanPoints, nodes := createSimpleNetwork(ht, cfg, 2, openChannelParams)
|
chanPoints, nodes := ht.CreateSimpleNetwork(cfgs, openChannelParams)
|
||||||
|
|
||||||
// Unwrap the results.
|
// Unwrap the results.
|
||||||
chanPoint := chanPoints[0]
|
chanPoint := chanPoints[0]
|
||||||
@@ -1780,67 +1788,6 @@ func testSweepCommitOutputAndAnchor(ht *lntest.HarnessTest) {
|
|||||||
ht.MineBlocksAndAssertNumTxes(1, 2)
|
ht.MineBlocksAndAssertNumTxes(1, 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
// createSimpleNetwork creates the specified number of nodes and makes a
|
|
||||||
// topology of `node1 -> node2 -> node3...`. Each node is created using the
|
|
||||||
// specified config, the neighbors are connected, and the channels are opened.
|
|
||||||
// Each node will be funded with a single UTXO of 1 BTC except the last one.
|
|
||||||
func createSimpleNetwork(ht *lntest.HarnessTest, nodeCfg []string,
|
|
||||||
numNodes int, p lntest.OpenChannelParams) ([]*lnrpc.ChannelPoint,
|
|
||||||
[]*node.HarnessNode) {
|
|
||||||
|
|
||||||
// Make a slice of nodes.
|
|
||||||
nodes := make([]*node.HarnessNode, numNodes)
|
|
||||||
|
|
||||||
// Create new nodes.
|
|
||||||
for i := range nodes {
|
|
||||||
nodeName := fmt.Sprintf("Node%q", string(rune('A'+i)))
|
|
||||||
n := ht.NewNode(nodeName, nodeCfg)
|
|
||||||
nodes[i] = n
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connect the nodes in a chain.
|
|
||||||
for i := 1; i < len(nodes); i++ {
|
|
||||||
nodeA := nodes[i-1]
|
|
||||||
nodeB := nodes[i]
|
|
||||||
ht.EnsureConnected(nodeA, nodeB)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fund all the nodes expect the last one.
|
|
||||||
for i := 0; i < len(nodes)-1; i++ {
|
|
||||||
node := nodes[i]
|
|
||||||
ht.FundCoinsUnconfirmed(btcutil.SatoshiPerBitcoin, node)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mine 1 block to get the above coins confirmed.
|
|
||||||
ht.MineBlocksAndAssertNumTxes(1, numNodes-1)
|
|
||||||
|
|
||||||
// Open channels in batch to save blocks mined.
|
|
||||||
reqs := make([]*lntest.OpenChannelRequest, 0, len(nodes)-1)
|
|
||||||
for i := 0; i < len(nodes)-1; i++ {
|
|
||||||
nodeA := nodes[i]
|
|
||||||
nodeB := nodes[i+1]
|
|
||||||
|
|
||||||
req := &lntest.OpenChannelRequest{
|
|
||||||
Local: nodeA,
|
|
||||||
Remote: nodeB,
|
|
||||||
Param: p,
|
|
||||||
}
|
|
||||||
reqs = append(reqs, req)
|
|
||||||
}
|
|
||||||
resp := ht.OpenMultiChannelsAsync(reqs)
|
|
||||||
|
|
||||||
// Make sure the nodes know each other's channels if they are public.
|
|
||||||
if !p.Private {
|
|
||||||
for _, node := range nodes {
|
|
||||||
for _, chanPoint := range resp {
|
|
||||||
ht.AssertTopologyChannelOpen(node, chanPoint)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp, nodes
|
|
||||||
}
|
|
||||||
|
|
||||||
// testBumpFee checks that when a new input is requested, it's first bumped via
|
// testBumpFee checks that when a new input is requested, it's first bumped via
|
||||||
// CPFP, then RBF. Along the way, we check the `BumpFee` can properly update
|
// CPFP, then RBF. Along the way, we check the `BumpFee` can properly update
|
||||||
// the fee function used by supplying new params.
|
// the fee function used by supplying new params.
|
||||||
@@ -2185,9 +2132,10 @@ func testBumpForceCloseFee(ht *lntest.HarnessTest) {
|
|||||||
cfg := []string{
|
cfg := []string{
|
||||||
"--protocol.anchors",
|
"--protocol.anchors",
|
||||||
}
|
}
|
||||||
|
cfgs := [][]string{cfg, cfg}
|
||||||
|
|
||||||
// Create a two hop network: Alice -> Bob.
|
// Create a two hop network: Alice -> Bob.
|
||||||
chanPoints, nodes := createSimpleNetwork(ht, cfg, 2, openChannelParams)
|
chanPoints, nodes := ht.CreateSimpleNetwork(cfgs, openChannelParams)
|
||||||
|
|
||||||
// Unwrap the results.
|
// Unwrap the results.
|
||||||
chanPoint := chanPoints[0]
|
chanPoint := chanPoints[0]
|
||||||
|
|||||||
+11
-21
@@ -31,7 +31,11 @@ func testZeroConfChannelOpen(ht *lntest.HarnessTest) {
|
|||||||
"--protocol.anchors",
|
"--protocol.anchors",
|
||||||
}
|
}
|
||||||
|
|
||||||
bob := ht.Bob
|
bob := ht.NewNode("Bob", nil)
|
||||||
|
|
||||||
|
// We'll give Bob some coins in order to fund the channel.
|
||||||
|
ht.FundCoins(btcutil.SatoshiPerBitcoin, bob)
|
||||||
|
|
||||||
carol := ht.NewNode("Carol", scidAliasArgs)
|
carol := ht.NewNode("Carol", scidAliasArgs)
|
||||||
ht.EnsureConnected(bob, carol)
|
ht.EnsureConnected(bob, carol)
|
||||||
|
|
||||||
@@ -40,7 +44,7 @@ func testZeroConfChannelOpen(ht *lntest.HarnessTest) {
|
|||||||
p := lntest.OpenChannelParams{
|
p := lntest.OpenChannelParams{
|
||||||
Amt: chanAmt,
|
Amt: chanAmt,
|
||||||
}
|
}
|
||||||
chanPoint := ht.OpenChannel(bob, carol, p)
|
ht.OpenChannel(bob, carol, p)
|
||||||
|
|
||||||
// Spin-up Dave so Carol can open a zero-conf channel to him.
|
// Spin-up Dave so Carol can open a zero-conf channel to him.
|
||||||
dave := ht.NewNode("Dave", scidAliasArgs)
|
dave := ht.NewNode("Dave", scidAliasArgs)
|
||||||
@@ -182,9 +186,6 @@ func testZeroConfChannelOpen(ht *lntest.HarnessTest) {
|
|||||||
ht.CompletePaymentRequests(
|
ht.CompletePaymentRequests(
|
||||||
dave, []string{eveInvoiceResp.PaymentRequest},
|
dave, []string{eveInvoiceResp.PaymentRequest},
|
||||||
)
|
)
|
||||||
|
|
||||||
// Close standby node's channels.
|
|
||||||
ht.CloseChannel(bob, chanPoint)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// testOptionScidAlias checks that opening an option_scid_alias channel-type
|
// testOptionScidAlias checks that opening an option_scid_alias channel-type
|
||||||
@@ -239,7 +240,11 @@ func optionScidAliasScenario(ht *lntest.HarnessTest, chantype, private bool) {
|
|||||||
"--protocol.anchors",
|
"--protocol.anchors",
|
||||||
}
|
}
|
||||||
|
|
||||||
bob := ht.Bob
|
bob := ht.NewNode("Bob", nil)
|
||||||
|
|
||||||
|
// We'll give Bob some coins in order to fund the channel.
|
||||||
|
ht.FundCoins(btcutil.SatoshiPerBitcoin, bob)
|
||||||
|
|
||||||
carol := ht.NewNode("Carol", scidAliasArgs)
|
carol := ht.NewNode("Carol", scidAliasArgs)
|
||||||
dave := ht.NewNode("Dave", scidAliasArgs)
|
dave := ht.NewNode("Dave", scidAliasArgs)
|
||||||
|
|
||||||
@@ -285,21 +290,6 @@ func optionScidAliasScenario(ht *lntest.HarnessTest, chantype, private bool) {
|
|||||||
}
|
}
|
||||||
fundingPoint2 := ht.OpenChannel(bob, carol, p)
|
fundingPoint2 := ht.OpenChannel(bob, carol, p)
|
||||||
|
|
||||||
defer func() {
|
|
||||||
// TODO(yy): remove the sleep once the following bug is fixed.
|
|
||||||
// When the payment is reported as settled by Bob, it's
|
|
||||||
// expected the commitment dance is finished and all subsequent
|
|
||||||
// states have been updated. Yet we'd receive the error `cannot
|
|
||||||
// co-op close channel with active htlcs` or `link failed to
|
|
||||||
// shutdown` if we close the channel. We need to investigate
|
|
||||||
// the order of settling the payments and updating commitments
|
|
||||||
// to understand and fix.
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
|
|
||||||
// Close standby node's channels.
|
|
||||||
ht.CloseChannel(bob, fundingPoint2)
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Wait until Dave receives the Bob<->Carol channel.
|
// Wait until Dave receives the Bob<->Carol channel.
|
||||||
ht.AssertTopologyChannelOpen(dave, fundingPoint2)
|
ht.AssertTopologyChannelOpen(dave, fundingPoint2)
|
||||||
|
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ func (f *FeeService) SetMinRelayFeerate(fee chainfee.SatPerKVByte) {
|
|||||||
func (f *FeeService) Reset() {
|
func (f *FeeService) Reset() {
|
||||||
f.lock.Lock()
|
f.lock.Lock()
|
||||||
f.feeRateMap = make(map[uint32]uint32)
|
f.feeRateMap = make(map[uint32]uint32)
|
||||||
|
f.minRelayFeerate = chainfee.FeePerKwFloor.FeePerKVByte()
|
||||||
f.lock.Unlock()
|
f.lock.Unlock()
|
||||||
|
|
||||||
// Initialize default fee estimate.
|
// Initialize default fee estimate.
|
||||||
|
|||||||
@@ -909,6 +909,18 @@ func (h *HarnessTest) validateNodeState(hn *node.HarnessNode) error {
|
|||||||
"delete all of them properly", hn.Name())
|
"delete all of them properly", hn.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The number of public edges should be zero.
|
||||||
|
if hn.State.Edge.Public != 0 {
|
||||||
|
return fmt.Errorf("%s: found active public egdes, please "+
|
||||||
|
"clean them properly", hn.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
// The number of edges should be zero.
|
||||||
|
if hn.State.Edge.Total != 0 {
|
||||||
|
return fmt.Errorf("%s: found active edges, please "+
|
||||||
|
"clean them properly", hn.Name())
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2197,3 +2209,155 @@ func (h *HarnessTest) SendCoins(a, b *node.HarnessNode,
|
|||||||
|
|
||||||
return tx
|
return tx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateSimpleNetwork creates the number of nodes specified by the number of
|
||||||
|
// configs and makes a topology of `node1 -> node2 -> node3...`. Each node is
|
||||||
|
// created using the specified config, the neighbors are connected, and the
|
||||||
|
// channels are opened. Each node will be funded with a single UTXO of 1 BTC
|
||||||
|
// except the last one.
|
||||||
|
//
|
||||||
|
// For instance, to create a network with 2 nodes that share the same node
|
||||||
|
// config,
|
||||||
|
//
|
||||||
|
// cfg := []string{"--protocol.anchors"}
|
||||||
|
// cfgs := [][]string{cfg, cfg}
|
||||||
|
// params := OpenChannelParams{...}
|
||||||
|
// chanPoints, nodes := ht.CreateSimpleNetwork(cfgs, params)
|
||||||
|
//
|
||||||
|
// This will create two nodes and open an anchor channel between them.
|
||||||
|
func (h *HarnessTest) CreateSimpleNetwork(nodeCfgs [][]string,
|
||||||
|
p OpenChannelParams) ([]*lnrpc.ChannelPoint, []*node.HarnessNode) {
|
||||||
|
|
||||||
|
// Create new nodes.
|
||||||
|
nodes := h.createNodes(nodeCfgs)
|
||||||
|
|
||||||
|
var resp []*lnrpc.ChannelPoint
|
||||||
|
|
||||||
|
// Open zero-conf channels if specified.
|
||||||
|
if p.ZeroConf {
|
||||||
|
resp = h.openZeroConfChannelsForNodes(nodes, p)
|
||||||
|
} else {
|
||||||
|
// Open channels between the nodes.
|
||||||
|
resp = h.openChannelsForNodes(nodes, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, nodes
|
||||||
|
}
|
||||||
|
|
||||||
|
// acceptChannel is used to accept a single channel that comes across. This
|
||||||
|
// should be run in a goroutine and is used to test nodes with the zero-conf
|
||||||
|
// feature bit.
|
||||||
|
func acceptChannel(t *testing.T, zeroConf bool, stream rpc.AcceptorClient) {
|
||||||
|
req, err := stream.Recv()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
resp := &lnrpc.ChannelAcceptResponse{
|
||||||
|
Accept: true,
|
||||||
|
PendingChanId: req.PendingChanId,
|
||||||
|
ZeroConf: zeroConf,
|
||||||
|
}
|
||||||
|
err = stream.Send(resp)
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// createNodes creates the number of nodes specified by the number of configs.
|
||||||
|
// Each node is created using the specified config, the neighbors are
|
||||||
|
// connected.
|
||||||
|
func (h *HarnessTest) createNodes(nodeCfgs [][]string) []*node.HarnessNode {
|
||||||
|
// Get the number of nodes.
|
||||||
|
numNodes := len(nodeCfgs)
|
||||||
|
|
||||||
|
// Make a slice of nodes.
|
||||||
|
nodes := make([]*node.HarnessNode, numNodes)
|
||||||
|
|
||||||
|
// Create new nodes.
|
||||||
|
for i, nodeCfg := range nodeCfgs {
|
||||||
|
nodeName := fmt.Sprintf("Node%q", string(rune('A'+i)))
|
||||||
|
n := h.NewNode(nodeName, nodeCfg)
|
||||||
|
nodes[i] = n
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect the nodes in a chain.
|
||||||
|
for i := 1; i < len(nodes); i++ {
|
||||||
|
nodeA := nodes[i-1]
|
||||||
|
nodeB := nodes[i]
|
||||||
|
h.EnsureConnected(nodeA, nodeB)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fund all the nodes expect the last one.
|
||||||
|
for i := 0; i < len(nodes)-1; i++ {
|
||||||
|
node := nodes[i]
|
||||||
|
h.FundCoinsUnconfirmed(btcutil.SatoshiPerBitcoin, node)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mine 1 block to get the above coins confirmed.
|
||||||
|
h.MineBlocksAndAssertNumTxes(1, numNodes-1)
|
||||||
|
|
||||||
|
return nodes
|
||||||
|
}
|
||||||
|
|
||||||
|
// openChannelsForNodes takes a list of nodes and makes a topology of `node1 ->
|
||||||
|
// node2 -> node3...`.
|
||||||
|
func (h *HarnessTest) openChannelsForNodes(nodes []*node.HarnessNode,
|
||||||
|
p OpenChannelParams) []*lnrpc.ChannelPoint {
|
||||||
|
|
||||||
|
// Sanity check the params.
|
||||||
|
require.False(h, p.ZeroConf, "zero-conf channels must be disabled")
|
||||||
|
require.Greater(h, len(nodes), 1, "need at least 2 nodes")
|
||||||
|
|
||||||
|
// Open channels in batch to save blocks mined.
|
||||||
|
reqs := make([]*OpenChannelRequest, 0, len(nodes)-1)
|
||||||
|
for i := 0; i < len(nodes)-1; i++ {
|
||||||
|
nodeA := nodes[i]
|
||||||
|
nodeB := nodes[i+1]
|
||||||
|
|
||||||
|
req := &OpenChannelRequest{
|
||||||
|
Local: nodeA,
|
||||||
|
Remote: nodeB,
|
||||||
|
Param: p,
|
||||||
|
}
|
||||||
|
reqs = append(reqs, req)
|
||||||
|
}
|
||||||
|
resp := h.OpenMultiChannelsAsync(reqs)
|
||||||
|
|
||||||
|
// Make sure the nodes know each other's channels if they are public.
|
||||||
|
if !p.Private {
|
||||||
|
for _, node := range nodes {
|
||||||
|
for _, chanPoint := range resp {
|
||||||
|
h.AssertTopologyChannelOpen(node, chanPoint)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp
|
||||||
|
}
|
||||||
|
|
||||||
|
// openZeroConfChannelsForNodes takes a list of nodes and makes a topology of
|
||||||
|
// `node1 -> node2 -> node3...` with zero-conf channels.
|
||||||
|
func (h *HarnessTest) openZeroConfChannelsForNodes(nodes []*node.HarnessNode,
|
||||||
|
p OpenChannelParams) []*lnrpc.ChannelPoint {
|
||||||
|
|
||||||
|
// Sanity check the params.
|
||||||
|
require.True(h, p.ZeroConf, "zero-conf channels must be enabled")
|
||||||
|
require.Greater(h, len(nodes), 1, "need at least 2 nodes")
|
||||||
|
|
||||||
|
// We are opening numNodes-1 channels.
|
||||||
|
cancels := make([]context.CancelFunc, 0, len(nodes)-1)
|
||||||
|
|
||||||
|
// Create the channel acceptors.
|
||||||
|
for _, node := range nodes[1:] {
|
||||||
|
acceptor, cancel := node.RPC.ChannelAcceptor()
|
||||||
|
go acceptChannel(h.T, true, acceptor)
|
||||||
|
|
||||||
|
cancels = append(cancels, cancel)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open channels between the nodes.
|
||||||
|
resp := h.openChannelsForNodes(nodes, p)
|
||||||
|
|
||||||
|
for _, cancel := range cancels {
|
||||||
|
cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp
|
||||||
|
}
|
||||||
@@ -19,6 +19,7 @@ import (
|
|||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
|
"github.com/lightningnetwork/lnd/fn"
|
||||||
"github.com/lightningnetwork/lnd/lnrpc"
|
"github.com/lightningnetwork/lnd/lnrpc"
|
||||||
"github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
|
"github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
|
||||||
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
|
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
|
||||||
@@ -239,6 +240,59 @@ func (h *HarnessTest) EnsureConnected(a, b *node.HarnessNode) {
|
|||||||
h.AssertPeerConnected(b, a)
|
h.AssertPeerConnected(b, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AssertNumActiveEdges checks that an expected number of active edges can be
|
||||||
|
// found in the node specified.
|
||||||
|
func (h *HarnessTest) AssertNumActiveEdges(hn *node.HarnessNode,
|
||||||
|
expected int, includeUnannounced bool) []*lnrpc.ChannelEdge {
|
||||||
|
|
||||||
|
var edges []*lnrpc.ChannelEdge
|
||||||
|
|
||||||
|
old := hn.State.Edge.Public
|
||||||
|
if includeUnannounced {
|
||||||
|
old = hn.State.Edge.Total
|
||||||
|
}
|
||||||
|
|
||||||
|
// filterDisabled is a helper closure that filters out disabled
|
||||||
|
// channels.
|
||||||
|
filterDisabled := func(edge *lnrpc.ChannelEdge) bool {
|
||||||
|
if edge.Node1Policy.Disabled {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if edge.Node2Policy.Disabled {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
err := wait.NoError(func() error {
|
||||||
|
req := &lnrpc.ChannelGraphRequest{
|
||||||
|
IncludeUnannounced: includeUnannounced,
|
||||||
|
}
|
||||||
|
resp := hn.RPC.DescribeGraph(req)
|
||||||
|
activeEdges := fn.Filter(filterDisabled, resp.Edges)
|
||||||
|
total := len(activeEdges)
|
||||||
|
|
||||||
|
if total-old == expected {
|
||||||
|
if expected != 0 {
|
||||||
|
// NOTE: assume edges come in ascending order
|
||||||
|
// that the old edges are at the front of the
|
||||||
|
// slice.
|
||||||
|
edges = activeEdges[old:]
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return errNumNotMatched(hn.Name(), "num of channel edges",
|
||||||
|
expected, total-old, total, old)
|
||||||
|
}, DefaultTimeout)
|
||||||
|
|
||||||
|
require.NoError(h, err, "timeout while checking for edges")
|
||||||
|
|
||||||
|
return edges
|
||||||
|
}
|
||||||
|
|
||||||
// AssertNumEdges checks that an expected number of edges can be found in the
|
// AssertNumEdges checks that an expected number of edges can be found in the
|
||||||
// node specified.
|
// node specified.
|
||||||
func (h *HarnessTest) AssertNumEdges(hn *node.HarnessNode,
|
func (h *HarnessTest) AssertNumEdges(hn *node.HarnessNode,
|
||||||
@@ -255,15 +309,15 @@ func (h *HarnessTest) AssertNumEdges(hn *node.HarnessNode,
|
|||||||
req := &lnrpc.ChannelGraphRequest{
|
req := &lnrpc.ChannelGraphRequest{
|
||||||
IncludeUnannounced: includeUnannounced,
|
IncludeUnannounced: includeUnannounced,
|
||||||
}
|
}
|
||||||
chanGraph := hn.RPC.DescribeGraph(req)
|
resp := hn.RPC.DescribeGraph(req)
|
||||||
total := len(chanGraph.Edges)
|
total := len(resp.Edges)
|
||||||
|
|
||||||
if total-old == expected {
|
if total-old == expected {
|
||||||
if expected != 0 {
|
if expected != 0 {
|
||||||
// NOTE: assume edges come in ascending order
|
// NOTE: assume edges come in ascending order
|
||||||
// that the old edges are at the front of the
|
// that the old edges are at the front of the
|
||||||
// slice.
|
// slice.
|
||||||
edges = chanGraph.Edges[old:]
|
edges = resp.Edges[old:]
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
+16
-2
@@ -7,6 +7,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
|
"github.com/lightningnetwork/lnd/fn"
|
||||||
"github.com/lightningnetwork/lnd/lnrpc"
|
"github.com/lightningnetwork/lnd/lnrpc"
|
||||||
"github.com/lightningnetwork/lnd/lnrpc/walletrpc"
|
"github.com/lightningnetwork/lnd/lnrpc/walletrpc"
|
||||||
"github.com/lightningnetwork/lnd/lntest/rpc"
|
"github.com/lightningnetwork/lnd/lntest/rpc"
|
||||||
@@ -308,13 +309,26 @@ func (s *State) updateUTXOStats() {
|
|||||||
|
|
||||||
// updateEdgeStats counts the total edges.
|
// updateEdgeStats counts the total edges.
|
||||||
func (s *State) updateEdgeStats() {
|
func (s *State) updateEdgeStats() {
|
||||||
|
// filterDisabled is a helper closure that filters out disabled
|
||||||
|
// channels.
|
||||||
|
filterDisabled := func(edge *lnrpc.ChannelEdge) bool {
|
||||||
|
if edge.Node1Policy.Disabled {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if edge.Node2Policy.Disabled {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
req := &lnrpc.ChannelGraphRequest{IncludeUnannounced: true}
|
req := &lnrpc.ChannelGraphRequest{IncludeUnannounced: true}
|
||||||
resp := s.rpc.DescribeGraph(req)
|
resp := s.rpc.DescribeGraph(req)
|
||||||
s.Edge.Total = len(resp.Edges)
|
s.Edge.Total = len(fn.Filter(filterDisabled, resp.Edges))
|
||||||
|
|
||||||
req = &lnrpc.ChannelGraphRequest{IncludeUnannounced: false}
|
req = &lnrpc.ChannelGraphRequest{IncludeUnannounced: false}
|
||||||
resp = s.rpc.DescribeGraph(req)
|
resp = s.rpc.DescribeGraph(req)
|
||||||
s.Edge.Public = len(resp.Edges)
|
s.Edge.Public = len(fn.Filter(filterDisabled, resp.Edges))
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateWalletBalance creates stats for the node's wallet balance.
|
// updateWalletBalance creates stats for the node's wallet balance.
|
||||||
|
|||||||
Reference in new issue
Block a user