@@ -11,6 +11,7 @@ import (
11
11
sphinx "github.com/lightningnetwork/lightning-onion"
12
12
"github.com/lightningnetwork/lnd/channeldb"
13
13
"github.com/lightningnetwork/lnd/feature"
14
+ "github.com/lightningnetwork/lnd/htlcswitch/hop"
14
15
"github.com/lightningnetwork/lnd/lnwire"
15
16
"github.com/lightningnetwork/lnd/record"
16
17
"github.com/lightningnetwork/lnd/routing/route"
@@ -105,6 +106,36 @@ type finalHopParams struct {
105
106
metadata []byte
106
107
}
107
108
109
+ // useAttrErrors returns true if the path can use attributable errors.
110
+ func useAttrErrors (pathEdges []* channeldb.CachedEdgePolicy ) bool {
111
+ // Use legacy errors if the route length exceeds the maximum number of
112
+ // hops for attributable errors.
113
+ if len (pathEdges ) > hop .AttrErrorStruct .HopCount () {
114
+ return false
115
+ }
116
+
117
+ // Every node along the path must signal support for attributable
118
+ // errors.
119
+ for _ , edge := range pathEdges {
120
+ // Get the node features.
121
+ toFeat := edge .ToNodeFeatures
122
+
123
+ // If there are no features known, assume the node cannot handle
124
+ // attributable errors.
125
+ if toFeat == nil {
126
+ return false
127
+ }
128
+
129
+ // If the node does not signal support for attributable errors,
130
+ // do not use them.
131
+ if ! toFeat .HasFeature (lnwire .AttributableErrorsOptional ) {
132
+ return false
133
+ }
134
+ }
135
+
136
+ return true
137
+ }
138
+
108
139
// newRoute constructs a route using the provided path and final hop constraints.
109
140
// Any destination specific fields from the final hop params will be attached
110
141
// assuming the destination's feature vector signals support, otherwise this
@@ -117,7 +148,7 @@ type finalHopParams struct {
117
148
// dependencies.
118
149
func newRoute (sourceVertex route.Vertex ,
119
150
pathEdges []* channeldb.CachedEdgePolicy , currentHeight uint32 ,
120
- finalHop finalHopParams ) (* route.Route , error ) {
151
+ finalHop finalHopParams , attrErrors bool ) (* route.Route , error ) {
121
152
122
153
var (
123
154
hops []* route.Hop
@@ -134,6 +165,9 @@ func newRoute(sourceVertex route.Vertex,
134
165
nextIncomingAmount lnwire.MilliSatoshi
135
166
)
136
167
168
+ // Use attributable errors if enabled and supported by the route.
169
+ attributableErrors := attrErrors && useAttrErrors (pathEdges )
170
+
137
171
pathLength := len (pathEdges )
138
172
for i := pathLength - 1 ; i >= 0 ; i -- {
139
173
// Now we'll start to calculate the items within the per-hop
@@ -250,6 +284,7 @@ func newRoute(sourceVertex route.Vertex,
250
284
CustomRecords : customRecords ,
251
285
MPP : mpp ,
252
286
Metadata : metadata ,
287
+ AttrError : attributableErrors ,
253
288
}
254
289
255
290
hops = append ([]* route.Hop {currentHop }, hops ... )
@@ -371,6 +406,10 @@ type PathFindingConfig struct {
371
406
// MinProbability defines the minimum success probability of the
372
407
// returned route.
373
408
MinProbability float64
409
+
410
+ // AttrErrors indicates whether we should use the new attributable
411
+ // errors if the nodes on the route allow it.
412
+ AttrErrors bool
374
413
}
375
414
376
415
// getOutgoingBalance returns the maximum available balance in any of the
0 commit comments