@@ -34,10 +34,17 @@ type OnionMessageUpdate struct {
3434 // blinded routes by default.
3535 OnionBlob []byte
3636
37+ // CustomRecords contains any custom TLV records included in the
38+ // payload.
3739 CustomRecords record.CustomSet
3840
41+ // ReplyPath contains the reply path information for the onion message.
3942 ReplyPath * lnwire.ReplyPath
4043
44+ // EncryptedRecipientData contains the encrypted recipient data for the
45+ // onion message, created by the creator of the blinded route. This is
46+ // the receiver for the last leg of the route, and the sender for the
47+ // first leg uyp to the introduction point.
4148 EncryptedRecipientData []byte
4249}
4350
@@ -72,7 +79,14 @@ var _ msgmux.Endpoint = (*OnionEndpoint)(nil)
7279
7380// NewOnionEndpoint creates a new OnionEndpoint with the given options.
7481func NewOnionEndpoint (receptionist * actor.Receptionist , router * sphinx.Router ,
75- opts ... OnionEndpointOption ) * OnionEndpoint {
82+ opts ... OnionEndpointOption ) (* OnionEndpoint , error ) {
83+
84+ if receptionist == nil {
85+ return nil , ErrNilReceptionist
86+ }
87+ if router == nil {
88+ return nil , ErrNilRouter
89+ }
7690
7791 o := & OnionEndpoint {
7892 receptionist : receptionist ,
@@ -82,7 +96,7 @@ func NewOnionEndpoint(receptionist *actor.Receptionist, router *sphinx.Router,
8296 opt (o )
8397 }
8498
85- return o
99+ return o , nil
86100}
87101
88102// Name returns the unique name of the endpoint.
@@ -118,49 +132,62 @@ func (o *OnionEndpoint) SendMessage(ctx context.Context,
118132 btclog .HexN ("onion_blob" , onionMsg .OnionBlob , 10 ),
119133 slog .Int ("blob_length" , len (onionMsg .OnionBlob )))
120134
121- routingDecisionResult := processOnionMessage (o .router , onionMsg )
135+ routingActionResult := processOnionMessage (o .router , onionMsg )
122136
123- routingDecision , err := routingDecisionResult .Unpack ()
137+ routingAction , err := routingActionResult .Unpack ()
124138 if err != nil {
125139 log .ErrorS (logCtx , "Failed to handle onion message" , err )
126140 return false
127141 }
128142
129- var payload * lnwire.OnionMessagePayload
130-
131- routingDecision .WhenLeft (func (forwardAction ForwardAction ) {
132- err = o .forwardMessage (
133- ctx , forwardAction .NextNodeID ,
134- forwardAction .NextPathKey ,
135- forwardAction .NextPacket ,
136- )
137- payload = forwardAction .Payload
138- })
139-
140- if err != nil {
141- log .ErrorS (logCtx , "Failed to forward onion message" , err )
142- return false
143- }
144-
145- routingDecision .WhenRight (func (deliverAction DeliverAction ) {
146- payload = deliverAction .Payload
147- })
148-
143+ var isProcessedSuccessful bool = false
144+
145+ // Handle the routing action.
146+ payload := fn .ElimEither (routingAction ,
147+ func (forwardAction forwardAction ) * lnwire.OnionMessagePayload {
148+ log .DebugS (logCtx , "Forwarding onion message" ,
149+ lnutils .LogPubKey ("next_node_id" ,
150+ forwardAction .nextNodeID ),
151+ )
152+
153+ err := o .forwardMessage (
154+ ctx , forwardAction .nextNodeID ,
155+ forwardAction .nextPathKey ,
156+ forwardAction .nextPacket ,
157+ )
158+
159+ if err != nil {
160+ log .ErrorS (logCtx , "Failed to forward onion " +
161+ "message" , err )
162+ isProcessedSuccessful = false
163+ }
164+
165+ isProcessedSuccessful = true
166+
167+ return forwardAction .payload
168+ },
169+ func (deliverAction deliverAction ) * lnwire.OnionMessagePayload {
170+ log .DebugS (logCtx , "Delivering onion message to self" )
171+ isProcessedSuccessful = true
172+ return deliverAction .payload
173+ })
174+
175+ // Convert peer []byte to [33]byte.
149176 var peerArr [33 ]byte
150177 copy (peerArr [:], peer )
151178
152179 // Convert path key []byte to [33]byte.
153- pathKey := onionMsg .PathKey .SerializeCompressed ()
154180 var pathKeyArr [33 ]byte
155- copy (pathKeyArr [:], pathKey )
181+ copy (pathKeyArr [:], onionMsg . PathKey . SerializeCompressed () )
156182
183+ // Create the onion message update to send to subscribers.
157184 update := & OnionMessageUpdate {
158185 Peer : peerArr ,
159186 PathKey : pathKeyArr ,
160187 OnionBlob : onionMsg .OnionBlob ,
161188 }
162189
163- // If we have a payload (no error) , add its contents to our update.
190+ // If we have a payload, add its contents to our update.
164191 if payload != nil {
165192 customRecords := make (record.CustomSet )
166193 for _ , v := range payload .FinalHopPayloads {
@@ -173,18 +200,17 @@ func (o *OnionEndpoint) SendMessage(ctx context.Context,
173200
174201 // Send the update to any subscribers.
175202 if sendErr := o .onionMessageServer .SendUpdate (update ); sendErr != nil {
176- log .Errorf ("Failed to send onion message update: %v" , sendErr )
177- return false
178- }
203+ log .ErrorS (logCtx , "Failed to send onion message update" ,
204+ sendErr )
179205
180- // If we failed to handle the onion message, we return false.
181- if err != nil {
182206 return false
183207 }
184208
185- return true
209+ return isProcessedSuccessful
186210}
187211
212+ // forwardMessage forwards the onion message to the next node using the peer
213+ // actor that was spawned for that node.
188214func (o * OnionEndpoint ) forwardMessage (ctx context.Context ,
189215 nextNodeID * btcec.PublicKey , nextBlindingPoint * btcec.PublicKey ,
190216 nextPacket []byte ) error {
@@ -195,25 +221,24 @@ func (o *OnionEndpoint) forwardMessage(ctx context.Context,
195221 // Find the onion peer actor for the next node ID.
196222 actorRefOpt := findPeerActor (o .receptionist , nextNodeIDBytes )
197223
224+ // If no actor found, return an error.
198225 if actorRefOpt .IsNone () {
199- return fmt .Errorf ("no actors found for nextNodeId: %v" ,
226+ return fmt .Errorf ("failed to forward onion message: no peer " +
227+ "actor found for node %v (peer may be disconnected)" ,
200228 nextNodeID )
201229 }
202230
203- onionMsg := lnwire .NewOnionMessage (
204- nextBlindingPoint , nextPacket ,
205- )
206- req := & OMRequest {msg : * onionMsg }
207- actorRefOpt .UnsafeFromSome ().Tell (ctx , req )
231+ // Send the onion message to the peer actor.
232+ actorRefOpt .WhenSome (func (actorRef actor.ActorRef [* OMRequest ,
233+ * OMResponse ]) {
208234
209- return nil
210- }
211-
212- func findPeerActor (receptionist * actor.Receptionist , pubKey [33 ]byte ,
213- ) fn.Option [actor.ActorRef [* OMRequest , * OMResponse ]] {
235+ onionMsg := lnwire .NewOnionMessage (
236+ nextBlindingPoint , nextPacket ,
237+ )
238+ req := & OMRequest {msg : * onionMsg }
239+ actorRef .Tell (ctx , req )
240+ })
214241
215- pubKeyHex := hex .EncodeToString (pubKey [:])
216- serviceKey := actor.NewServiceKey [* OMRequest , * OMResponse ](pubKeyHex )
217- refs := actor .FindInReceptionist (receptionist , serviceKey )
218- return fn .Head (refs )
242+ // Successfully forwarded the message.
243+ return nil
219244}
0 commit comments