lnd_test: refactor out waitForChannelUpdate and assertChannelPolicy

This commit is contained in:
Wilmer Paulino 2018-04-30 16:55:31 -04:00
parent a9d873d248
commit b2585f33ad
No known key found for this signature in database
GPG Key ID: 6DF57B9F9514972F

@ -674,6 +674,135 @@ func testBasicChannelFunding(net *lntest.NetworkHarness, t *harnessTest) {
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
// gets propagated to other nodes in the network.
func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
@ -746,162 +875,46 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
feeRate := int64(12)
timeLockDelta := uint32(66)
expectedPolicy := &lnrpc.RoutingPolicy{
FeeBaseMsat: baseFee,
FeeRateMilliMsat: feeBase * feeRate,
TimeLockDelta: timeLockDelta,
}
req := &lnrpc.PolicyUpdateRequest{
BaseFeeMsat: baseFee,
FeeRate: float64(feeRate),
TimeLockDelta: timeLockDelta,
}
req.Scope = &lnrpc.PolicyUpdateRequest_ChanPoint{
ChanPoint: chanPoint,
Scope: &lnrpc.PolicyUpdateRequest_ChanPoint{
ChanPoint: chanPoint,
},
}
_, err = net.Bob.UpdateChannelPolicy(ctxb, req)
if err != nil {
if _, err := net.Bob.UpdateChannelPolicy(ctxb, req); err != nil {
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.
waitForChannelUpdate(aliceUpdates, net.Bob.PubKeyStr, chanPoint)
waitForChannelUpdate(bobUpdates, net.Bob.PubKeyStr, chanPoint)
waitForChannelUpdate(carolUpdates, net.Bob.PubKeyStr, chanPoint)
// assertChannelPolicy asserts that the passed node's known channel
// policy for the passed chanPoint is consistent with Bob's current
// expected policy values.
assertChannelPolicy := func(node *lntest.HarnessNode,
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")
}
}
waitForChannelUpdate(
t, aliceUpdates, net.Bob.PubKeyStr, expectedPolicy, chanPoint,
)
waitForChannelUpdate(
t, bobUpdates, net.Bob.PubKeyStr, expectedPolicy, chanPoint,
)
waitForChannelUpdate(
t, carolUpdates, net.Bob.PubKeyStr, expectedPolicy, chanPoint,
)
// Check that all nodes now know about Bob's updated policy.
assertChannelPolicy(net.Alice, net.Bob.PubKeyStr, chanPoint)
assertChannelPolicy(net.Bob, net.Bob.PubKeyStr, chanPoint)
assertChannelPolicy(carol, net.Bob.PubKeyStr, chanPoint)
assertChannelPolicy(
t, net.Alice, net.Bob.PubKeyStr, expectedPolicy, 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
// 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)
timeLockDelta = uint32(22)
expectedPolicy.FeeBaseMsat = baseFee
expectedPolicy.FeeRateMilliMsat = feeBase * feeRate
expectedPolicy.TimeLockDelta = timeLockDelta
req = &lnrpc.PolicyUpdateRequest{
BaseFeeMsat: baseFee,
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
// Alice's channels.
waitForChannelUpdate(
aliceUpdates, net.Alice.PubKeyStr, chanPoint, chanPoint3,
t, aliceUpdates, net.Alice.PubKeyStr, expectedPolicy, chanPoint,
chanPoint3,
)
waitForChannelUpdate(
bobUpdates, net.Alice.PubKeyStr, chanPoint, chanPoint3,
t, bobUpdates, net.Alice.PubKeyStr, expectedPolicy, chanPoint,
chanPoint3,
)
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
// received.
assertChannelPolicy(net.Alice, net.Alice.PubKeyStr, chanPoint)
assertChannelPolicy(net.Bob, net.Alice.PubKeyStr, chanPoint)
assertChannelPolicy(carol, net.Alice.PubKeyStr, chanPoint)
assertChannelPolicy(net.Alice, net.Alice.PubKeyStr, chanPoint3)
assertChannelPolicy(net.Bob, net.Alice.PubKeyStr, chanPoint3)
assertChannelPolicy(carol, net.Alice.PubKeyStr, chanPoint3)
assertChannelPolicy(
t, net.Alice, net.Alice.PubKeyStr, expectedPolicy, chanPoint,
chanPoint3,
)
assertChannelPolicy(
t, net.Bob, net.Alice.PubKeyStr, expectedPolicy, chanPoint,
chanPoint3,
)
assertChannelPolicy(
t, carol, net.Alice.PubKeyStr, expectedPolicy, chanPoint,
chanPoint3,
)
// Close the channels.
ctxt, _ = context.WithTimeout(ctxb, timeout)