mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-06-20 13:53:19 +02:00
localchans: do error if an edge policy is missing
This commit is contained in:
parent
20f7c73801
commit
266531271b
@ -99,8 +99,22 @@ func (r *Manager) UpdatePolicy(newSchema routing.ChannelPolicy,
|
|||||||
// will be used to report invalid channels later on.
|
// will be used to report invalid channels later on.
|
||||||
delete(unprocessedChans, info.ChannelPoint)
|
delete(unprocessedChans, info.ChannelPoint)
|
||||||
|
|
||||||
|
if edge == nil {
|
||||||
|
log.Errorf("Got nil channel edge policy when updating "+
|
||||||
|
"a channel. Channel point: %v",
|
||||||
|
info.ChannelPoint.String())
|
||||||
|
|
||||||
|
failedUpdates = append(failedUpdates, makeFailureItem(
|
||||||
|
info.ChannelPoint,
|
||||||
|
lnrpc.UpdateFailure_UPDATE_FAILURE_NOT_FOUND,
|
||||||
|
"edge policy not found",
|
||||||
|
))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Apply the new policy to the edge.
|
// Apply the new policy to the edge.
|
||||||
edge, err := r.updateEdge(
|
err := r.updateEdge(
|
||||||
tx, info.ChannelPoint, edge, newSchema,
|
tx, info.ChannelPoint, edge, newSchema,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -173,49 +187,30 @@ func (r *Manager) UpdatePolicy(newSchema routing.ChannelPolicy,
|
|||||||
"not yet confirmed",
|
"not yet confirmed",
|
||||||
))
|
))
|
||||||
|
|
||||||
|
// If the edge was not found, but the channel is found, that
|
||||||
|
// means the edge is missing in the graph database and should be
|
||||||
|
// recreated. The edge and policy are created in-memory. The
|
||||||
|
// edge is inserted in createEdge below and the policy will be
|
||||||
|
// added to the graph in the PropagateChanPolicyUpdate call
|
||||||
|
// below.
|
||||||
case createMissingEdge:
|
case createMissingEdge:
|
||||||
// If the edge was not found, but the channel is found,
|
|
||||||
// that means the edge is missing in the graph database
|
|
||||||
// and should be recreated. The edge and policy are
|
|
||||||
// created in-memory. The edge is inserted in createEdge
|
|
||||||
// below and the policy will be added to the graph in
|
|
||||||
// the PropagateChanPolicyUpdate call below.
|
|
||||||
log.Warnf("Missing edge for active channel (%s) "+
|
log.Warnf("Missing edge for active channel (%s) "+
|
||||||
"during policy update. Recreating edge with "+
|
"during policy update. Recreating edge with "+
|
||||||
"default policy.",
|
"default policy.",
|
||||||
channel.FundingOutpoint.String())
|
channel.FundingOutpoint.String())
|
||||||
|
|
||||||
info, edge, err := r.createEdge(channel, time.Now())
|
info, edge, failedUpdate := r.createMissingEdge(
|
||||||
if err != nil {
|
channel, newSchema,
|
||||||
log.Errorf("Failed to recreate missing edge "+
|
)
|
||||||
"for channel (%s): %v",
|
if failedUpdate == nil {
|
||||||
channel.FundingOutpoint.String(), err)
|
err = processChan(nil, info, edge)
|
||||||
|
if err != nil {
|
||||||
f := lnrpc.UpdateFailure_UPDATE_FAILURE_UNKNOWN
|
return nil, err
|
||||||
failedUpdates = append(failedUpdates,
|
}
|
||||||
makeFailureItem(chanPoint, f,
|
} else {
|
||||||
"could not update policies",
|
failedUpdates = append(
|
||||||
))
|
failedUpdates, failedUpdate,
|
||||||
}
|
)
|
||||||
|
|
||||||
// Insert the edge into the database to avoid `edge not
|
|
||||||
// found` errors during policy update propagation.
|
|
||||||
err = r.AddEdge(info)
|
|
||||||
if err != nil {
|
|
||||||
log.Warnf("Attempt to add missing edge for "+
|
|
||||||
"channel (%s) errored with: %v",
|
|
||||||
channel.FundingOutpoint.String(), err)
|
|
||||||
|
|
||||||
f := lnrpc.UpdateFailure_UPDATE_FAILURE_UNKNOWN
|
|
||||||
failedUpdates = append(failedUpdates,
|
|
||||||
makeFailureItem(chanPoint, f,
|
|
||||||
"could not add edge",
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
err = processChan(nil, info, edge)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -247,6 +242,52 @@ func (r *Manager) UpdatePolicy(newSchema routing.ChannelPolicy,
|
|||||||
return failedUpdates, nil
|
return failedUpdates, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Manager) createMissingEdge(channel *channeldb.OpenChannel,
|
||||||
|
newSchema routing.ChannelPolicy) (*models.ChannelEdgeInfo,
|
||||||
|
*models.ChannelEdgePolicy, *lnrpc.FailedUpdate) {
|
||||||
|
|
||||||
|
info, edge, err := r.createEdge(channel, time.Now())
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Failed to recreate missing edge "+
|
||||||
|
"for channel (%s): %v",
|
||||||
|
channel.FundingOutpoint.String(), err)
|
||||||
|
|
||||||
|
return nil, nil, makeFailureItem(
|
||||||
|
channel.FundingOutpoint,
|
||||||
|
lnrpc.UpdateFailure_UPDATE_FAILURE_UNKNOWN,
|
||||||
|
"could not update policies",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the newly created edge policy with the user defined new
|
||||||
|
// schema before adding the edge to the database.
|
||||||
|
err = r.updateEdge(nil, channel.FundingOutpoint, edge, newSchema)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, makeFailureItem(
|
||||||
|
info.ChannelPoint,
|
||||||
|
lnrpc.UpdateFailure_UPDATE_FAILURE_INVALID_PARAMETER,
|
||||||
|
err.Error(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert the edge into the database to avoid `edge not
|
||||||
|
// found` errors during policy update propagation.
|
||||||
|
err = r.AddEdge(info)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Attempt to add missing edge for "+
|
||||||
|
"channel (%s) errored with: %v",
|
||||||
|
channel.FundingOutpoint.String(), err)
|
||||||
|
|
||||||
|
return nil, nil, makeFailureItem(
|
||||||
|
channel.FundingOutpoint,
|
||||||
|
lnrpc.UpdateFailure_UPDATE_FAILURE_UNKNOWN,
|
||||||
|
"could not add edge",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return info, edge, nil
|
||||||
|
}
|
||||||
|
|
||||||
// createEdge recreates an edge and policy from an open channel in-memory.
|
// createEdge recreates an edge and policy from an open channel in-memory.
|
||||||
func (r *Manager) createEdge(channel *channeldb.OpenChannel,
|
func (r *Manager) createEdge(channel *channeldb.OpenChannel,
|
||||||
timestamp time.Time) (*models.ChannelEdgeInfo,
|
timestamp time.Time) (*models.ChannelEdgeInfo,
|
||||||
@ -309,25 +350,14 @@ func (r *Manager) createEdge(channel *channeldb.OpenChannel,
|
|||||||
return info, edge, nil
|
return info, edge, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateEdge updates the given edge with the new schema. The edge parameter may
|
// updateEdge updates the given edge with the new schema.
|
||||||
// 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) (*models.ChannelEdgePolicy, error) {
|
newSchema routing.ChannelPolicy) error {
|
||||||
|
|
||||||
channel, err := r.FetchChannel(tx, chanPoint)
|
channel, err := r.FetchChannel(tx, chanPoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return 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.
|
||||||
@ -345,7 +375,7 @@ func (r *Manager) updateEdge(tx kvdb.RTx, chanPoint wire.OutPoint,
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
edge.TimeLockDelta = uint16(newSchema.TimeLockDelta)
|
edge.TimeLockDelta = uint16(newSchema.TimeLockDelta)
|
||||||
@ -353,7 +383,7 @@ func (r *Manager) updateEdge(tx kvdb.RTx, chanPoint wire.OutPoint,
|
|||||||
// Retrieve negotiated channel htlc amt limits.
|
// Retrieve negotiated channel htlc amt limits.
|
||||||
amtMin, amtMax, err := r.getHtlcAmtLimits(channel)
|
amtMin, amtMax, err := r.getHtlcAmtLimits(channel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// We now update the edge max htlc value.
|
// We now update the edge max htlc value.
|
||||||
@ -386,19 +416,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 nil, fmt.Errorf(
|
return 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 nil, fmt.Errorf(
|
return 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 nil, fmt.Errorf(
|
return 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,
|
||||||
)
|
)
|
||||||
@ -407,7 +437,7 @@ 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 edge, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getHtlcAmtLimits retrieves the negotiated channel min and max htlc amount
|
// getHtlcAmtLimits retrieves the negotiated channel min and max htlc amount
|
||||||
|
Loading…
x
Reference in New Issue
Block a user