localchans: add policy when missing

This commit is contained in:
Jesse de Wit
2024-10-31 12:56:44 +01:00
parent 5e5291d044
commit 7d9d100e94
2 changed files with 49 additions and 21 deletions

View File

@@ -39,7 +39,7 @@ type Manager struct {
edgesToUpdate []discovery.EdgeWithInfo) error edgesToUpdate []discovery.EdgeWithInfo) error
// ForAllOutgoingChannels is required to iterate over all our local // ForAllOutgoingChannels is required to iterate over all our local
// channels. // channels. The ChannelEdgePolicy parameter may be nil.
ForAllOutgoingChannels func(cb func(kvdb.RTx, ForAllOutgoingChannels func(cb func(kvdb.RTx,
*models.ChannelEdgeInfo, *models.ChannelEdgeInfo,
*models.ChannelEdgePolicy) error) error *models.ChannelEdgePolicy) error) error
@@ -82,6 +82,7 @@ func (r *Manager) UpdatePolicy(newSchema routing.ChannelPolicy,
var edgesToUpdate []discovery.EdgeWithInfo var edgesToUpdate []discovery.EdgeWithInfo
policiesToUpdate := make(map[wire.OutPoint]models.ForwardingPolicy) policiesToUpdate := make(map[wire.OutPoint]models.ForwardingPolicy)
// NOTE: edge may be nil when this function is called.
processChan := func( processChan := func(
tx kvdb.RTx, tx kvdb.RTx,
info *models.ChannelEdgeInfo, info *models.ChannelEdgeInfo,
@@ -99,7 +100,9 @@ func (r *Manager) UpdatePolicy(newSchema routing.ChannelPolicy,
delete(unprocessedChans, info.ChannelPoint) delete(unprocessedChans, info.ChannelPoint)
// Apply the new policy to the edge. // Apply the new policy to the edge.
err := r.updateEdge(tx, info.ChannelPoint, edge, newSchema) edge, err := r.updateEdge(
tx, info.ChannelPoint, edge, newSchema,
)
if err != nil { if err != nil {
failedUpdates = append(failedUpdates, failedUpdates = append(failedUpdates,
makeFailureItem(info.ChannelPoint, makeFailureItem(info.ChannelPoint,
@@ -306,10 +309,26 @@ func (r *Manager) createEdge(channel *channeldb.OpenChannel,
return info, edge, nil return info, edge, nil
} }
// updateEdge updates the given edge with the new schema. // updateEdge updates the given edge with the new schema. The edge parameter may
// be nil, in that case a new channel policy is returned. In other cases the
// passed in channel policy is returned after modification.
func (r *Manager) updateEdge(tx kvdb.RTx, chanPoint wire.OutPoint, func (r *Manager) updateEdge(tx kvdb.RTx, chanPoint wire.OutPoint,
edge *models.ChannelEdgePolicy, edge *models.ChannelEdgePolicy,
newSchema routing.ChannelPolicy) error { newSchema routing.ChannelPolicy) (*models.ChannelEdgePolicy, error) {
channel, err := r.FetchChannel(tx, chanPoint)
if err != nil {
return nil, err
}
// If due to some unforeseen circumstances the policy doesn't exist,
// recreate it here.
if edge == nil {
_, edge, err = r.createEdge(channel, time.Now())
if err != nil {
return nil, err
}
}
// Update forwarding fee scheme and required time lock delta. // Update forwarding fee scheme and required time lock delta.
edge.FeeBaseMSat = newSchema.BaseFee edge.FeeBaseMSat = newSchema.BaseFee
@@ -318,7 +337,7 @@ func (r *Manager) updateEdge(tx kvdb.RTx, chanPoint wire.OutPoint,
) )
// If inbound fees are set, we update the edge with them. // If inbound fees are set, we update the edge with them.
err := fn.MapOptionZ(newSchema.InboundFee, err = fn.MapOptionZ(newSchema.InboundFee,
func(f models.InboundFee) error { func(f models.InboundFee) error {
inboundWireFee := f.ToWire() inboundWireFee := f.ToWire()
return edge.ExtraOpaqueData.PackRecords( return edge.ExtraOpaqueData.PackRecords(
@@ -326,15 +345,15 @@ func (r *Manager) updateEdge(tx kvdb.RTx, chanPoint wire.OutPoint,
) )
}) })
if err != nil { if err != nil {
return err return nil, err
} }
edge.TimeLockDelta = uint16(newSchema.TimeLockDelta) edge.TimeLockDelta = uint16(newSchema.TimeLockDelta)
// Retrieve negotiated channel htlc amt limits. // Retrieve negotiated channel htlc amt limits.
amtMin, amtMax, err := r.getHtlcAmtLimits(tx, chanPoint) amtMin, amtMax, err := r.getHtlcAmtLimits(channel)
if err != nil { if err != nil {
return err return nil, err
} }
// We now update the edge max htlc value. // We now update the edge max htlc value.
@@ -367,19 +386,19 @@ func (r *Manager) updateEdge(tx kvdb.RTx, chanPoint wire.OutPoint,
// Validate htlc amount constraints. // Validate htlc amount constraints.
switch { switch {
case edge.MinHTLC < amtMin: case edge.MinHTLC < amtMin:
return fmt.Errorf( return nil, fmt.Errorf(
"min htlc amount of %v is below min htlc parameter of %v", "min htlc amount of %v is below min htlc parameter of %v",
edge.MinHTLC, amtMin, edge.MinHTLC, amtMin,
) )
case edge.MaxHTLC > amtMax: case edge.MaxHTLC > amtMax:
return fmt.Errorf( return nil, fmt.Errorf(
"max htlc size of %v is above max pending amount of %v", "max htlc size of %v is above max pending amount of %v",
edge.MaxHTLC, amtMax, edge.MaxHTLC, amtMax,
) )
case edge.MinHTLC > edge.MaxHTLC: case edge.MinHTLC > edge.MaxHTLC:
return fmt.Errorf( return nil, fmt.Errorf(
"min_htlc %v greater than max_htlc %v", "min_htlc %v greater than max_htlc %v",
edge.MinHTLC, edge.MaxHTLC, edge.MinHTLC, edge.MaxHTLC,
) )
@@ -388,19 +407,14 @@ func (r *Manager) updateEdge(tx kvdb.RTx, chanPoint wire.OutPoint,
// Clear signature to help prevent usage of the previous signature. // Clear signature to help prevent usage of the previous signature.
edge.SetSigBytes(nil) edge.SetSigBytes(nil)
return nil return edge, nil
} }
// getHtlcAmtLimits retrieves the negotiated channel min and max htlc amount // getHtlcAmtLimits retrieves the negotiated channel min and max htlc amount
// constraints. // constraints.
func (r *Manager) getHtlcAmtLimits(tx kvdb.RTx, chanPoint wire.OutPoint) ( func (r *Manager) getHtlcAmtLimits(ch *channeldb.OpenChannel) (
lnwire.MilliSatoshi, lnwire.MilliSatoshi, error) { lnwire.MilliSatoshi, lnwire.MilliSatoshi, error) {
ch, err := r.FetchChannel(tx, chanPoint)
if err != nil {
return 0, 0, err
}
// The max htlc policy field must be less than or equal to the channel // The max htlc policy field must be less than or equal to the channel
// capacity AND less than or equal to the max in-flight HTLC value. // capacity AND less than or equal to the max in-flight HTLC value.
// Since the latter is always less than or equal to the former, just // Since the latter is always less than or equal to the former, just

View File

@@ -1110,11 +1110,25 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
ScidCloser: scidCloserMan, ScidCloser: scidCloserMan,
}, nodeKeyDesc) }, nodeKeyDesc)
selfVertex := route.Vertex(nodeKeyDesc.PubKey.SerializeCompressed())
//nolint:lll //nolint:lll
s.localChanMgr = &localchans.Manager{ s.localChanMgr = &localchans.Manager{
SelfPub: nodeKeyDesc.PubKey, SelfPub: nodeKeyDesc.PubKey,
DefaultRoutingPolicy: cc.RoutingPolicy, DefaultRoutingPolicy: cc.RoutingPolicy,
ForAllOutgoingChannels: s.graphBuilder.ForAllOutgoingChannels, ForAllOutgoingChannels: func(cb func(kvdb.RTx,
*models.ChannelEdgeInfo, *models.ChannelEdgePolicy) error) error {
return s.graphDB.ForEachNodeChannel(selfVertex,
func(tx kvdb.RTx, c *models.ChannelEdgeInfo,
e *models.ChannelEdgePolicy,
_ *models.ChannelEdgePolicy) error {
// NOTE: The invoked callback here may
// receive a nil channel policy.
return cb(tx, c, e)
},
)
},
PropagateChanPolicyUpdate: s.authGossiper.PropagateChanPolicyUpdate, PropagateChanPolicyUpdate: s.authGossiper.PropagateChanPolicyUpdate,
UpdateForwardingPolicies: s.htlcSwitch.UpdateForwardingPolicies, UpdateForwardingPolicies: s.htlcSwitch.UpdateForwardingPolicies,
FetchChannel: s.chanStateDB.FetchChannel, FetchChannel: s.chanStateDB.FetchChannel,