lnd_test: refactor out waitForChannelUpdate and assertChannelPolicy
This commit is contained in:
parent
a9d873d248
commit
b2585f33ad
331
lnd_test.go
331
lnd_test.go
@ -674,6 +674,135 @@ func testBasicChannelFunding(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
closeChannelAndAssert(ctxt, t, net, net.Alice, chanPoint, false)
|
closeChannelAndAssert(ctxt, t, net, net.Alice, chanPoint, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// txStr returns the string representation of the channel's funding transaction.
|
||||||
|
func txStr(chanPoint *lnrpc.ChannelPoint) string {
|
||||||
|
txidHash, err := getChanPointFundingTxid(chanPoint)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
fundingTxID, err := chainhash.NewHash(txidHash)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
cp := wire.OutPoint{
|
||||||
|
Hash: *fundingTxID,
|
||||||
|
Index: chanPoint.OutputIndex,
|
||||||
|
}
|
||||||
|
return cp.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// waitForChannelUpdate waits for a node to receive updates from the advertising
|
||||||
|
// node for the specified channels.
|
||||||
|
func waitForChannelUpdate(t *harnessTest, graphUpdates chan *lnrpc.GraphTopologyUpdate,
|
||||||
|
advertisingNode string, expectedPolicy *lnrpc.RoutingPolicy,
|
||||||
|
chanPoints ...*lnrpc.ChannelPoint) {
|
||||||
|
|
||||||
|
// Create a set containing all the channel points we are awaiting
|
||||||
|
// updates for.
|
||||||
|
cps := make(map[string]struct{})
|
||||||
|
for _, chanPoint := range chanPoints {
|
||||||
|
cps[txStr(chanPoint)] = struct{}{}
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case graphUpdate := <-graphUpdates:
|
||||||
|
for _, update := range graphUpdate.ChannelUpdates {
|
||||||
|
fundingTxStr := txStr(update.ChanPoint)
|
||||||
|
if _, ok := cps[fundingTxStr]; !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if update.AdvertisingNode != advertisingNode {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
err := checkChannelPolicy(
|
||||||
|
update.RoutingPolicy, expectedPolicy,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// We got a policy update that matched the
|
||||||
|
// values and channel point of what we
|
||||||
|
// expected, delete it from the map.
|
||||||
|
delete(cps, fundingTxStr)
|
||||||
|
|
||||||
|
// If we have no more channel points we are
|
||||||
|
// waiting for, break out of the loop.
|
||||||
|
if len(cps) == 0 {
|
||||||
|
break out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case <-time.After(20 * time.Second):
|
||||||
|
t.Fatalf("did not receive channel update")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// assertChannelPolicy asserts that the passed node's known channel policy for
|
||||||
|
// the passed chanPoint is consistent with the expected policy values.
|
||||||
|
func assertChannelPolicy(t *harnessTest, node *lntest.HarnessNode,
|
||||||
|
advertisingNode string, expectedPolicy *lnrpc.RoutingPolicy,
|
||||||
|
chanPoints ...*lnrpc.ChannelPoint) {
|
||||||
|
|
||||||
|
descReq := &lnrpc.ChannelGraphRequest{}
|
||||||
|
chanGraph, err := node.DescribeGraph(context.Background(), descReq)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to query for alice's graph: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
for _, chanPoint := range chanPoints {
|
||||||
|
for _, e := range chanGraph.Edges {
|
||||||
|
if e.ChanPoint != txStr(chanPoint) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
if e.Node1Pub == advertisingNode {
|
||||||
|
err = checkChannelPolicy(
|
||||||
|
e.Node1Policy, expectedPolicy,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
err = checkChannelPolicy(
|
||||||
|
e.Node2Policy, expectedPolicy,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
continue out
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we've iterated over all the known edges and we weren't
|
||||||
|
// able to find this specific one, then we'll fail.
|
||||||
|
t.Fatalf("did not find edge %v", txStr(chanPoint))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkChannelPolicy checks that the policy matches the expected one.
|
||||||
|
func checkChannelPolicy(policy, expectedPolicy *lnrpc.RoutingPolicy) error {
|
||||||
|
if policy.FeeBaseMsat != expectedPolicy.FeeBaseMsat {
|
||||||
|
return fmt.Errorf("expected base fee %v, got %v",
|
||||||
|
expectedPolicy.FeeBaseMsat, policy.FeeBaseMsat)
|
||||||
|
}
|
||||||
|
if policy.FeeRateMilliMsat != expectedPolicy.FeeRateMilliMsat {
|
||||||
|
return fmt.Errorf("expected fee rate %v, got %v",
|
||||||
|
expectedPolicy.FeeRateMilliMsat,
|
||||||
|
policy.FeeRateMilliMsat)
|
||||||
|
}
|
||||||
|
if policy.TimeLockDelta != expectedPolicy.TimeLockDelta {
|
||||||
|
return fmt.Errorf("expected time lock delta %v, got %v",
|
||||||
|
expectedPolicy.TimeLockDelta,
|
||||||
|
policy.TimeLockDelta)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// testUpdateChannelPolicy tests that policy updates made to a channel
|
// testUpdateChannelPolicy tests that policy updates made to a channel
|
||||||
// gets propagated to other nodes in the network.
|
// gets propagated to other nodes in the network.
|
||||||
func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
|
func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
|
||||||
@ -746,162 +875,46 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
feeRate := int64(12)
|
feeRate := int64(12)
|
||||||
timeLockDelta := uint32(66)
|
timeLockDelta := uint32(66)
|
||||||
|
|
||||||
|
expectedPolicy := &lnrpc.RoutingPolicy{
|
||||||
|
FeeBaseMsat: baseFee,
|
||||||
|
FeeRateMilliMsat: feeBase * feeRate,
|
||||||
|
TimeLockDelta: timeLockDelta,
|
||||||
|
}
|
||||||
|
|
||||||
req := &lnrpc.PolicyUpdateRequest{
|
req := &lnrpc.PolicyUpdateRequest{
|
||||||
BaseFeeMsat: baseFee,
|
BaseFeeMsat: baseFee,
|
||||||
FeeRate: float64(feeRate),
|
FeeRate: float64(feeRate),
|
||||||
TimeLockDelta: timeLockDelta,
|
TimeLockDelta: timeLockDelta,
|
||||||
}
|
Scope: &lnrpc.PolicyUpdateRequest_ChanPoint{
|
||||||
req.Scope = &lnrpc.PolicyUpdateRequest_ChanPoint{
|
|
||||||
ChanPoint: chanPoint,
|
ChanPoint: chanPoint,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = net.Bob.UpdateChannelPolicy(ctxb, req)
|
if _, err := net.Bob.UpdateChannelPolicy(ctxb, req); err != nil {
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unable to get alice's balance: %v", err)
|
t.Fatalf("unable to get alice's balance: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// txStr returns the string representation of the channel's
|
|
||||||
// funding tx.
|
|
||||||
txStr := func(chanPoint *lnrpc.ChannelPoint) string {
|
|
||||||
txidHash, err := getChanPointFundingTxid(chanPoint)
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
fundingTxID, err := chainhash.NewHash(txidHash)
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
cp := wire.OutPoint{
|
|
||||||
Hash: *fundingTxID,
|
|
||||||
Index: chanPoint.OutputIndex,
|
|
||||||
}
|
|
||||||
return cp.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// A closure that is used to wait for a channel updates that matches
|
|
||||||
// the channel policy update done by Alice.
|
|
||||||
waitForChannelUpdate := func(graphUpdates chan *lnrpc.GraphTopologyUpdate,
|
|
||||||
advertisingNode string, chanPoints ...*lnrpc.ChannelPoint) {
|
|
||||||
|
|
||||||
// Create a map containing all the channel points we are
|
|
||||||
// waiting for updates for.
|
|
||||||
cps := make(map[string]bool)
|
|
||||||
for _, chanPoint := range chanPoints {
|
|
||||||
cps[txStr(chanPoint)] = true
|
|
||||||
}
|
|
||||||
Loop:
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case graphUpdate := <-graphUpdates:
|
|
||||||
for _, update := range graphUpdate.ChannelUpdates {
|
|
||||||
fundingTxStr := txStr(update.ChanPoint)
|
|
||||||
if _, ok := cps[fundingTxStr]; !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if update.AdvertisingNode != advertisingNode {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
policy := update.RoutingPolicy
|
|
||||||
if policy.FeeBaseMsat != baseFee {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if policy.FeeRateMilliMsat != feeRate*feeBase {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if policy.TimeLockDelta != timeLockDelta {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// We got a policy update that matched the
|
|
||||||
// values and channel point of what we
|
|
||||||
// expected, delete it from the map.
|
|
||||||
delete(cps, fundingTxStr)
|
|
||||||
|
|
||||||
// If we have no more channel points we are
|
|
||||||
// waiting for, break out of the loop.
|
|
||||||
if len(cps) == 0 {
|
|
||||||
break Loop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case <-time.After(20 * time.Second):
|
|
||||||
t.Fatalf("did not receive channel update")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for all nodes to have seen the policy update done by Bob.
|
// Wait for all nodes to have seen the policy update done by Bob.
|
||||||
waitForChannelUpdate(aliceUpdates, net.Bob.PubKeyStr, chanPoint)
|
waitForChannelUpdate(
|
||||||
waitForChannelUpdate(bobUpdates, net.Bob.PubKeyStr, chanPoint)
|
t, aliceUpdates, net.Bob.PubKeyStr, expectedPolicy, chanPoint,
|
||||||
waitForChannelUpdate(carolUpdates, net.Bob.PubKeyStr, chanPoint)
|
)
|
||||||
|
waitForChannelUpdate(
|
||||||
// assertChannelPolicy asserts that the passed node's known channel
|
t, bobUpdates, net.Bob.PubKeyStr, expectedPolicy, chanPoint,
|
||||||
// policy for the passed chanPoint is consistent with Bob's current
|
)
|
||||||
// expected policy values.
|
waitForChannelUpdate(
|
||||||
assertChannelPolicy := func(node *lntest.HarnessNode,
|
t, carolUpdates, net.Bob.PubKeyStr, expectedPolicy, chanPoint,
|
||||||
advertisingNode string, chanPoint *lnrpc.ChannelPoint) {
|
)
|
||||||
|
|
||||||
// Get a DescribeGraph from the node.
|
|
||||||
descReq := &lnrpc.ChannelGraphRequest{}
|
|
||||||
chanGraph, err := node.DescribeGraph(ctxb, descReq)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unable to query for alice's routing table: %v",
|
|
||||||
err)
|
|
||||||
}
|
|
||||||
|
|
||||||
edgeFound := false
|
|
||||||
for _, e := range chanGraph.Edges {
|
|
||||||
if e.ChanPoint == txStr(chanPoint) {
|
|
||||||
edgeFound = true
|
|
||||||
if e.Node1Pub == advertisingNode {
|
|
||||||
if e.Node1Policy.FeeBaseMsat != baseFee {
|
|
||||||
t.Fatalf("expected base fee "+
|
|
||||||
"%v, got %v", baseFee,
|
|
||||||
e.Node1Policy.FeeBaseMsat)
|
|
||||||
}
|
|
||||||
if e.Node1Policy.FeeRateMilliMsat != feeRate*feeBase {
|
|
||||||
t.Fatalf("expected fee rate "+
|
|
||||||
"%v, got %v", feeRate*feeBase,
|
|
||||||
e.Node1Policy.FeeRateMilliMsat)
|
|
||||||
}
|
|
||||||
if e.Node1Policy.TimeLockDelta != timeLockDelta {
|
|
||||||
t.Fatalf("expected time lock "+
|
|
||||||
"delta %v, got %v",
|
|
||||||
timeLockDelta,
|
|
||||||
e.Node1Policy.TimeLockDelta)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if e.Node2Policy.FeeBaseMsat != baseFee {
|
|
||||||
t.Fatalf("expected base fee "+
|
|
||||||
"%v, got %v", baseFee,
|
|
||||||
e.Node2Policy.FeeBaseMsat)
|
|
||||||
}
|
|
||||||
if e.Node2Policy.FeeRateMilliMsat != feeRate*feeBase {
|
|
||||||
t.Fatalf("expected fee rate "+
|
|
||||||
"%v, got %v", feeRate*feeBase,
|
|
||||||
e.Node2Policy.FeeRateMilliMsat)
|
|
||||||
}
|
|
||||||
if e.Node2Policy.TimeLockDelta != timeLockDelta {
|
|
||||||
t.Fatalf("expected time lock "+
|
|
||||||
"delta %v, got %v",
|
|
||||||
timeLockDelta,
|
|
||||||
e.Node2Policy.TimeLockDelta)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !edgeFound {
|
|
||||||
t.Fatalf("did not find edge")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that all nodes now know about Bob's updated policy.
|
// Check that all nodes now know about Bob's updated policy.
|
||||||
assertChannelPolicy(net.Alice, net.Bob.PubKeyStr, chanPoint)
|
assertChannelPolicy(
|
||||||
assertChannelPolicy(net.Bob, net.Bob.PubKeyStr, chanPoint)
|
t, net.Alice, net.Bob.PubKeyStr, expectedPolicy, chanPoint,
|
||||||
assertChannelPolicy(carol, net.Bob.PubKeyStr, chanPoint)
|
)
|
||||||
|
assertChannelPolicy(
|
||||||
|
t, net.Bob, net.Bob.PubKeyStr, expectedPolicy, chanPoint,
|
||||||
|
)
|
||||||
|
assertChannelPolicy(
|
||||||
|
t, carol, net.Bob.PubKeyStr, expectedPolicy, chanPoint,
|
||||||
|
)
|
||||||
|
|
||||||
// Now that all nodes have received the new channel update, we'll try
|
// Now that all nodes have received the new channel update, we'll try
|
||||||
// to send a payment from Alice to Carol to ensure that Alice has
|
// to send a payment from Alice to Carol to ensure that Alice has
|
||||||
@ -951,6 +964,10 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
feeRate = int64(123)
|
feeRate = int64(123)
|
||||||
timeLockDelta = uint32(22)
|
timeLockDelta = uint32(22)
|
||||||
|
|
||||||
|
expectedPolicy.FeeBaseMsat = baseFee
|
||||||
|
expectedPolicy.FeeRateMilliMsat = feeBase * feeRate
|
||||||
|
expectedPolicy.TimeLockDelta = timeLockDelta
|
||||||
|
|
||||||
req = &lnrpc.PolicyUpdateRequest{
|
req = &lnrpc.PolicyUpdateRequest{
|
||||||
BaseFeeMsat: baseFee,
|
BaseFeeMsat: baseFee,
|
||||||
FeeRate: float64(feeRate),
|
FeeRate: float64(feeRate),
|
||||||
@ -966,24 +983,32 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
// Wait for all nodes to have seen the policy updates for both of
|
// Wait for all nodes to have seen the policy updates for both of
|
||||||
// Alice's channels.
|
// Alice's channels.
|
||||||
waitForChannelUpdate(
|
waitForChannelUpdate(
|
||||||
aliceUpdates, net.Alice.PubKeyStr, chanPoint, chanPoint3,
|
t, aliceUpdates, net.Alice.PubKeyStr, expectedPolicy, chanPoint,
|
||||||
|
chanPoint3,
|
||||||
)
|
)
|
||||||
waitForChannelUpdate(
|
waitForChannelUpdate(
|
||||||
bobUpdates, net.Alice.PubKeyStr, chanPoint, chanPoint3,
|
t, bobUpdates, net.Alice.PubKeyStr, expectedPolicy, chanPoint,
|
||||||
|
chanPoint3,
|
||||||
)
|
)
|
||||||
waitForChannelUpdate(
|
waitForChannelUpdate(
|
||||||
carolUpdates, net.Alice.PubKeyStr, chanPoint, chanPoint3,
|
t, carolUpdates, net.Alice.PubKeyStr, expectedPolicy, chanPoint,
|
||||||
|
chanPoint3,
|
||||||
)
|
)
|
||||||
|
|
||||||
// And finally check that all nodes remembers the policy update they
|
// And finally check that all nodes remembers the policy update they
|
||||||
// received.
|
// received.
|
||||||
assertChannelPolicy(net.Alice, net.Alice.PubKeyStr, chanPoint)
|
assertChannelPolicy(
|
||||||
assertChannelPolicy(net.Bob, net.Alice.PubKeyStr, chanPoint)
|
t, net.Alice, net.Alice.PubKeyStr, expectedPolicy, chanPoint,
|
||||||
assertChannelPolicy(carol, net.Alice.PubKeyStr, chanPoint)
|
chanPoint3,
|
||||||
|
)
|
||||||
assertChannelPolicy(net.Alice, net.Alice.PubKeyStr, chanPoint3)
|
assertChannelPolicy(
|
||||||
assertChannelPolicy(net.Bob, net.Alice.PubKeyStr, chanPoint3)
|
t, net.Bob, net.Alice.PubKeyStr, expectedPolicy, chanPoint,
|
||||||
assertChannelPolicy(carol, net.Alice.PubKeyStr, chanPoint3)
|
chanPoint3,
|
||||||
|
)
|
||||||
|
assertChannelPolicy(
|
||||||
|
t, carol, net.Alice.PubKeyStr, expectedPolicy, chanPoint,
|
||||||
|
chanPoint3,
|
||||||
|
)
|
||||||
|
|
||||||
// Close the channels.
|
// Close the channels.
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
|
Loading…
Reference in New Issue
Block a user