Replace MessageFlags and ChannelFlags bitfields in CachedEdgePolicy with explicit boolean fields to improve clarity and support both v1 and v2 channel updates: - Replace MessageFlags with HasMaxHTLC boolean. - Replace ChannelFlags with IsNode1 and IsDisabled booleans. - Update NewCachedPolicy to extract these fields version-appropriately: - For v1: derive from MessageFlags and ChannelFlags bits. - For v2: derive from policy.SecondPeer and policy.DisableFlags. Update all call sites that used method calls IsNode1() and IsDisabled() to instead access the fields directly. This includes: - graph_cache.go: policy direction and disable checks - unified_edges.go: HasMaxHTLC and IsDisabled checks - Tests: policy construction and assertions This refactoring improves readability by making the cached policy's state explicit rather than encoded in bitfields, and enables seamless support for both gossip protocol versions.
113 lines
4.0 KiB
Go
113 lines
4.0 KiB
Go
package models
|
|
|
|
import (
|
|
"github.com/lightningnetwork/lnd/fn/v2"
|
|
"github.com/lightningnetwork/lnd/lnwire"
|
|
"github.com/lightningnetwork/lnd/routing/route"
|
|
)
|
|
|
|
const (
|
|
// feeRateParts is the total number of parts used to express fee rates.
|
|
feeRateParts = 1e6
|
|
)
|
|
|
|
// CachedEdgePolicy is a struct that only caches the information of a
|
|
// ChannelEdgePolicy that we actually use for pathfinding and therefore need to
|
|
// store in the cache.
|
|
type CachedEdgePolicy struct {
|
|
// ChannelID is the unique channel ID for the channel. The first 3
|
|
// bytes are the block height, the next 3 the index within the block,
|
|
// and the last 2 bytes are the output index for the channel.
|
|
ChannelID uint64
|
|
|
|
// HasMaxHTLC indicates whether the policy has a max HTLC value.
|
|
HasMaxHTLC bool
|
|
|
|
// 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
|
|
// the node would like to HTLC exchanges.
|
|
TimeLockDelta uint16
|
|
|
|
// MinHTLC is the smallest value HTLC this node will forward, expressed
|
|
// in millisatoshi.
|
|
MinHTLC lnwire.MilliSatoshi
|
|
|
|
// MaxHTLC is the largest value HTLC this node will forward, expressed
|
|
// in millisatoshi.
|
|
MaxHTLC lnwire.MilliSatoshi
|
|
|
|
// FeeBaseMSat is the base HTLC fee that will be charged for forwarding
|
|
// ANY HTLC, expressed in mSAT's.
|
|
FeeBaseMSat lnwire.MilliSatoshi
|
|
|
|
// FeeProportionalMillionths is the rate that the node will charge for
|
|
// HTLCs for each millionth of a satoshi forwarded.
|
|
FeeProportionalMillionths lnwire.MilliSatoshi
|
|
|
|
// InboundFee is the fee that the node will charge for incoming HTLCs.
|
|
InboundFee fn.Option[lnwire.Fee]
|
|
|
|
// ToNodePubKey is a function that returns the to node of a policy.
|
|
// Since we only ever store the inbound policy, this is always the node
|
|
// that we query the channels for in ForEachChannel(). Therefore, we can
|
|
// save a lot of space by not storing this information in the memory and
|
|
// instead just set this function when we copy the policy from cache in
|
|
// ForEachChannel().
|
|
ToNodePubKey func() route.Vertex
|
|
|
|
// ToNodeFeatures are the to node's features. They are never set while
|
|
// the edge is in the cache, only on the copy that is returned in
|
|
// ForEachChannel().
|
|
ToNodeFeatures *lnwire.FeatureVector
|
|
}
|
|
|
|
// ComputeFee computes the fee to forward an HTLC of `amt` milli-satoshis over
|
|
// the passed active payment channel. This value is currently computed as
|
|
// specified in BOLT07, but will likely change in the near future.
|
|
func (c *CachedEdgePolicy) ComputeFee(
|
|
amt lnwire.MilliSatoshi) lnwire.MilliSatoshi {
|
|
|
|
return c.FeeBaseMSat + (amt*c.FeeProportionalMillionths)/feeRateParts
|
|
}
|
|
|
|
// 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,
|
|
HasMaxHTLC: true,
|
|
IsNode1: !policy.SecondPeer,
|
|
IsDisabled: !policy.DisableFlags.IsEnabled(),
|
|
TimeLockDelta: policy.TimeLockDelta,
|
|
MinHTLC: policy.MinHTLC,
|
|
MaxHTLC: policy.MaxHTLC,
|
|
FeeBaseMSat: policy.FeeBaseMSat,
|
|
FeeProportionalMillionths: policy.FeeProportionalMillionths,
|
|
InboundFee: policy.InboundFee,
|
|
}
|
|
}
|