diff --git a/graph/db/graph_cache.go b/graph/db/graph_cache.go index 4a3a3b0f9..7cf101fac 100644 --- a/graph/db/graph_cache.go +++ b/graph/db/graph_cache.go @@ -142,8 +142,8 @@ func (c *GraphCache) AddChannel(info *models.CachedEdgeInfo, // Skip adding policies if both are disabled, as the channel is // currently unusable for routing. However, we still add the channel // structure above so that policy updates can later enable it. - if policy1 != nil && policy1.IsDisabled() && - policy2 != nil && policy2.IsDisabled() { + if policy1 != nil && policy1.IsDisabled && + policy2 != nil && policy2.IsDisabled { log.Debugf("Skipping policies for channel %v: both "+ "policies are disabled (channel structure still "+ @@ -156,14 +156,14 @@ func (c *GraphCache) AddChannel(info *models.CachedEdgeInfo, // of node 2 then we have the policy 1 as seen from node 1. if policy1 != nil { fromNode, toNode := info.NodeKey1Bytes, info.NodeKey2Bytes - if !policy1.IsNode1() { + if !policy1.IsNode1 { fromNode, toNode = toNode, fromNode } c.UpdatePolicy(policy1, fromNode, toNode) } if policy2 != nil { fromNode, toNode := info.NodeKey2Bytes, info.NodeKey1Bytes - if policy2.IsNode1() { + if policy2.IsNode1 { fromNode, toNode = toNode, fromNode } c.UpdatePolicy(policy2, fromNode, toNode) @@ -210,7 +210,7 @@ func (c *GraphCache) UpdatePolicy(policy *models.CachedEdgePolicy, fromNode, switch { // This is node 1, and it is edge 1, so this is the outgoing // policy for node 1. - case channel.IsNode1 && policy.IsNode1(): + case channel.IsNode1 && policy.IsNode1: channel.OutPolicySet = true policy.InboundFee.WhenSome(func(fee lnwire.Fee) { channel.InboundFee = fee @@ -218,7 +218,7 @@ func (c *GraphCache) UpdatePolicy(policy *models.CachedEdgePolicy, fromNode, // This is node 2, and it is edge 2, so this is the outgoing // policy for node 2. - case !channel.IsNode1 && !policy.IsNode1(): + case !channel.IsNode1 && !policy.IsNode1: channel.OutPolicySet = true policy.InboundFee.WhenSome(func(fee lnwire.Fee) { channel.InboundFee = fee diff --git a/graph/db/graph_cache_test.go b/graph/db/graph_cache_test.go index 89e3a7e87..3d5fba85d 100644 --- a/graph/db/graph_cache_test.go +++ b/graph/db/graph_cache_test.go @@ -33,9 +33,9 @@ func TestGraphCacheAddNode(t *testing.T) { runTest := func(nodeA, nodeB route.Vertex) { t.Helper() - channelFlagA, channelFlagB := 0, 1 + isNode1A, isNode1B := true, false if nodeA == pubKey2 { - channelFlagA, channelFlagB = 1, 0 + isNode1A, isNode1B = false, true } inboundFee := lnwire.Fee{ @@ -44,8 +44,9 @@ func TestGraphCacheAddNode(t *testing.T) { } outPolicy1 := &models.CachedEdgePolicy{ - ChannelID: 1000, - ChannelFlags: lnwire.ChanUpdateChanFlags(channelFlagA), + ChannelID: 1000, + IsNode1: isNode1A, + IsDisabled: false, ToNodePubKey: func() route.Vertex { return nodeB }, @@ -53,8 +54,9 @@ func TestGraphCacheAddNode(t *testing.T) { InboundFee: fn.Some(inboundFee), } inPolicy1 := &models.CachedEdgePolicy{ - ChannelID: 1000, - ChannelFlags: lnwire.ChanUpdateChanFlags(channelFlagB), + ChannelID: 1000, + IsNode1: isNode1B, + IsDisabled: false, ToNodePubKey: func() route.Vertex { return nodeA }, @@ -125,8 +127,9 @@ func assertCachedPolicyEqual(t *testing.T, original, cached *models.CachedEdgePolicy) { require.Equal(t, original.ChannelID, cached.ChannelID) - require.Equal(t, original.MessageFlags, cached.MessageFlags) - require.Equal(t, original.ChannelFlags, cached.ChannelFlags) + require.Equal(t, original.HasMaxHTLC, cached.HasMaxHTLC) + require.Equal(t, original.IsNode1, cached.IsNode1) + require.Equal(t, original.IsDisabled, cached.IsDisabled) require.Equal(t, original.TimeLockDelta, cached.TimeLockDelta) require.Equal(t, original.MinHTLC, cached.MinHTLC) require.Equal(t, original.MaxHTLC, cached.MaxHTLC) @@ -171,13 +174,14 @@ func TestGraphCacheDisabledPoliciesRegression(t *testing.T) { // Create two disabled policies. disabledPolicy1 := &models.CachedEdgePolicy{ - ChannelID: chanID, - ChannelFlags: lnwire.ChanUpdateDisabled, + ChannelID: chanID, + IsNode1: true, + IsDisabled: true, } disabledPolicy2 := &models.CachedEdgePolicy{ - ChannelID: chanID, - ChannelFlags: lnwire.ChanUpdateDisabled | - lnwire.ChanUpdateDirection, + ChannelID: chanID, + IsNode1: false, + IsDisabled: true, } // Add the channel with both policies disabled (simulating @@ -207,7 +211,8 @@ func TestGraphCacheDisabledPoliciesRegression(t *testing.T) { // Now simulate receiving a fresh update enabling one direction. enabledPolicy1 := &models.CachedEdgePolicy{ ChannelID: chanID, - ChannelFlags: 0, // NOT disabled anymore + IsNode1: true, + IsDisabled: false, TimeLockDelta: 40, MinHTLC: lnwire.MilliSatoshi(1000), } diff --git a/graph/db/models/cached_edge_policy.go b/graph/db/models/cached_edge_policy.go index 40b0d9212..90c8d56c3 100644 --- a/graph/db/models/cached_edge_policy.go +++ b/graph/db/models/cached_edge_policy.go @@ -20,13 +20,15 @@ type CachedEdgePolicy struct { // and the last 2 bytes are the output index for the channel. ChannelID uint64 - // MessageFlags is a bitfield which indicates the presence of optional - // fields (like max_htlc) in the policy. - MessageFlags lnwire.ChanUpdateMsgFlags + // HasMaxHTLC indicates whether the policy has a max HTLC value. + HasMaxHTLC bool - // ChannelFlags is a bitfield which signals the capabilities of the - // channel as well as the directed edge this update applies to. - ChannelFlags lnwire.ChanUpdateChanFlags + // IsNode1 indicates whether this policy was announced by the channel's + // node_1. + IsNode1 bool + + // IsDisabled indicates whether the policy disables forwarding. + IsDisabled bool // TimeLockDelta is the number of blocks this node will subtract from // the expiry of an incoming HTLC. This value expresses the time buffer @@ -75,24 +77,31 @@ func (c *CachedEdgePolicy) ComputeFee( return c.FeeBaseMSat + (amt*c.FeeProportionalMillionths)/feeRateParts } -// IsDisabled returns true if the channel is disabled in the direction from the -// advertising node. -func (c *CachedEdgePolicy) IsDisabled() bool { - return c.ChannelFlags&lnwire.ChanUpdateDisabled != 0 -} - -// IsNode1 returns true if this policy was announced by the channel's node_1 -// node. -func (c *CachedEdgePolicy) IsNode1() bool { - return c.ChannelFlags&lnwire.ChanUpdateDirection == 0 -} - // NewCachedPolicy turns a full policy into a minimal one that can be cached. func NewCachedPolicy(policy *ChannelEdgePolicy) *CachedEdgePolicy { + if policy.Version != lnwire.GossipVersion2 { + return &CachedEdgePolicy{ + ChannelID: policy.ChannelID, + HasMaxHTLC: policy.MessageFlags.HasMaxHtlc(), + IsDisabled: policy.ChannelFlags& + lnwire.ChanUpdateDisabled != 0, + IsNode1: policy.ChannelFlags& + lnwire.ChanUpdateDirection == 0, + TimeLockDelta: policy.TimeLockDelta, + MinHTLC: policy.MinHTLC, + MaxHTLC: policy.MaxHTLC, + FeeBaseMSat: policy.FeeBaseMSat, + FeeProportionalMillionths: policy. + FeeProportionalMillionths, + InboundFee: policy.InboundFee, + } + } + return &CachedEdgePolicy{ ChannelID: policy.ChannelID, - MessageFlags: policy.MessageFlags, - ChannelFlags: policy.ChannelFlags, + HasMaxHTLC: true, + IsNode1: !policy.SecondPeer, + IsDisabled: !policy.DisableFlags.IsEnabled(), TimeLockDelta: policy.TimeLockDelta, MinHTLC: policy.MinHTLC, MaxHTLC: policy.MaxHTLC, diff --git a/routing/unified_edges.go b/routing/unified_edges.go index 9b8f6c5c0..fda06aabf 100644 --- a/routing/unified_edges.go +++ b/routing/unified_edges.go @@ -188,7 +188,7 @@ func (u *unifiedEdge) amtInRange(amt lnwire.MilliSatoshi) bool { } // Skip channels for which this htlc is too large. - if u.policy.MessageFlags.HasMaxHtlc() && + if u.policy.HasMaxHTLC && amt > u.policy.MaxHTLC { log.Tracef("Exceeds policy's MaxHTLC: amt=%v, MaxHTLC=%v", @@ -376,7 +376,7 @@ func (u *edgeUnifier) getEdgeNetwork(netAmtReceived lnwire.MilliSatoshi, } // For network channels, skip the disabled ones. - if edge.policy.IsDisabled() { + if edge.policy.IsDisabled { log.Debugf("Skipped edge %v due to it being disabled", edge.policy.ChannelID) continue @@ -385,7 +385,7 @@ func (u *edgeUnifier) getEdgeNetwork(netAmtReceived lnwire.MilliSatoshi, // Track the maximal capacity for usable channels. If we don't // know the capacity, we fall back to MaxHTLC. capMsat := lnwire.NewMSatFromSatoshis(edge.capacity) - if capMsat == 0 && edge.policy.MessageFlags.HasMaxHtlc() { + if capMsat == 0 && edge.policy.HasMaxHTLC { log.Tracef("No capacity available for channel %v, "+ "using MaxHtlcMsat (%v) as a fallback.", edge.policy.ChannelID, edge.policy.MaxHTLC) diff --git a/routing/unified_edges_test.go b/routing/unified_edges_test.go index 8fc79031a..25c8e9220 100644 --- a/routing/unified_edges_test.go +++ b/routing/unified_edges_test.go @@ -30,7 +30,7 @@ func TestNodeEdgeUnifier(t *testing.T) { FeeProportionalMillionths: 100000, FeeBaseMSat: 30, TimeLockDelta: 60, - MessageFlags: lnwire.ChanUpdateRequiredMaxHtlc, + HasMaxHTLC: true, MaxHTLC: 5000, MinHTLC: 100, } @@ -39,7 +39,7 @@ func TestNodeEdgeUnifier(t *testing.T) { FeeProportionalMillionths: 190000, FeeBaseMSat: 10, TimeLockDelta: 40, - MessageFlags: lnwire.ChanUpdateRequiredMaxHtlc, + HasMaxHTLC: true, MaxHTLC: 4000, MinHTLC: 100, }