Htlcswitch: rename Deobfuscator and Obfuscator interfaces

This commit renames the Deobfuscator interface to ErrorDecrypter and
the Obfuscator interface to ErrorEncrypter. With this rename, the
purpose of these two interfaces are a bit clearer.

Additionally, DecryptError (which was formerly Deobfuscate) now
directly returns an ForwardingError type instead of the
lnwire.FailureMessage.
This commit is contained in:
Olaoluwa Osuntokun 2017-10-10 19:36:52 -07:00
parent 30a46291f8
commit 12ae63101d
No known key found for this signature in database
GPG Key ID: 964EA263DD637C21
9 changed files with 109 additions and 93 deletions

@ -38,9 +38,9 @@ type paymentCircuit struct {
// request back. // request back.
Dest lnwire.ShortChannelID Dest lnwire.ShortChannelID
// Obfuscator is used to re-encrypt the onion failure before sending it // ErrorEncrypter is used to re-encrypt the onion failure before
// back to the originator of the payment. // sending it back to the originator of the payment.
Obfuscator Obfuscator ErrorEncrypter ErrorEncrypter
// RefCount is used to count the circuits with the same circuit key. // RefCount is used to count the circuits with the same circuit key.
RefCount int RefCount int
@ -48,13 +48,14 @@ type paymentCircuit struct {
// newPaymentCircuit creates new payment circuit instance. // newPaymentCircuit creates new payment circuit instance.
func newPaymentCircuit(src, dest lnwire.ShortChannelID, key circuitKey, func newPaymentCircuit(src, dest lnwire.ShortChannelID, key circuitKey,
obfuscator Obfuscator) *paymentCircuit { e ErrorEncrypter) *paymentCircuit {
return &paymentCircuit{ return &paymentCircuit{
Src: src, Src: src,
Dest: dest, Dest: dest,
PaymentHash: key, PaymentHash: key,
RefCount: 1, RefCount: 1,
Obfuscator: obfuscator, ErrorEncrypter: e,
} }
} }

@ -5,6 +5,7 @@ import (
"github.com/lightningnetwork/lightning-onion" "github.com/lightningnetwork/lightning-onion"
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
"github.com/roasbeef/btcd/btcec"
) )
// ForwardingError wraps an lnwire.FailureMessage in a struct that also // ForwardingError wraps an lnwire.FailureMessage in a struct that also
@ -17,45 +18,48 @@ type ForwardingError struct {
lnwire.FailureMessage lnwire.FailureMessage
} }
// ErrorDecrypter is an interface that is used to decrypt the onion encrypted
// failure reason an extra out a well formed error. // failure reason an extra out a well formed error.
type Deobfuscator interface { type ErrorDecrypter interface {
// Deobfuscate peels off each layer of onion encryption from the first // DecryptError peels off each layer of onion encryption from the first
// hop, to the source of the error. A fully populated // hop, to the source of the error. A fully populated
// lnwire.FailureMessage is returned. // lnwire.FailureMessage is returned along with the source of the
Deobfuscate(lnwire.OpaqueReason) (lnwire.FailureMessage, error) // error.
DecryptError(lnwire.OpaqueReason) (*ForwardingError, error)
} }
// Obfuscator is an interface that is used to encrypt HTLC related errors at // ErrorEncrypter is an interface that is used to encrypt HTLC related errors
// the source of the error, and also at each intermediate hop all the way back // at the source of the error, and also at each intermediate hop all the way
// to the source of the payment. // back to the source of the payment.
type Obfuscator interface { type ErrorEncrypter interface {
// InitialObfuscate is used to convert the failure into opaque // EncryptFirstHop transforms a concrete failure message into an
// reason.
// InitialObfuscate transforms a concrete failure message into an
// encrypted opaque failure reason. This method will be used at the // encrypted opaque failure reason. This method will be used at the
// source that the error occurs. It differs from BackwardObfuscate // source that the error occurs. It differs from IntermediateEncrypt
// slightly, in that it computes a proper MAC over the error. // slightly, in that it computes a proper MAC over the error.
InitialObfuscate(lnwire.FailureMessage) (lnwire.OpaqueReason, error) EncryptFirstHop(lnwire.FailureMessage) (lnwire.OpaqueReason, error)
// BackwardObfuscate wraps an already encrypted opaque reason error in // IntermediateEncrypt wraps an already encrypted opaque reason error
// an additional layer of onion encryption. This process repeats until // in an additional layer of onion encryption. This process repeats
// the error arrives at the source of the payment. // until the error arrives at the source of the payment.
BackwardObfuscate(lnwire.OpaqueReason) lnwire.OpaqueReason IntermediateEncrypt(lnwire.OpaqueReason) lnwire.OpaqueReason
} }
// FailureObfuscator is used to obfuscate the onion failure. // SphinxErrorEncrypter is a concrete implementation of both the ErrorEncrypter
type FailureObfuscator struct { // interface backed by an implementation of the Sphinx packet format. As a
*sphinx.OnionObfuscator // result, all errors handled are themselves wrapped in layers of onion
// encryption and must be treated as such accordingly.
type SphinxErrorEncrypter struct {
*sphinx.OnionErrorEncrypter
} }
// InitialObfuscate transforms a concrete failure message into an encrypted // EncryptFirstHop transforms a concrete failure message into an encrypted
// opaque failure reason. This method will be used at the source that the error // opaque failure reason. This method will be used at the source that the error
// occurs. It differs from BackwardObfuscate slightly, in that it computes a // occurs. It differs from BackwardObfuscate slightly, in that it computes a
// proper MAC over the error. // proper MAC over the error.
// //
// NOTE: Part of the Obfuscator interface. // NOTE: Part of the ErrorEncrypter interface.
func (o *FailureObfuscator) InitialObfuscate(failure lnwire.FailureMessage) (lnwire.OpaqueReason, error) { func (o *SphinxErrorEncrypter) EncryptFirstHop(failure lnwire.FailureMessage) (lnwire.OpaqueReason, error) {
var b bytes.Buffer var b bytes.Buffer
if err := lnwire.EncodeFailure(&b, failure, 0); err != nil { if err := lnwire.EncodeFailure(&b, failure, 0); err != nil {
return nil, err return nil, err
@ -63,46 +67,54 @@ func (o *FailureObfuscator) InitialObfuscate(failure lnwire.FailureMessage) (lnw
// We pass a true as the first parameter to indicate that a MAC should // We pass a true as the first parameter to indicate that a MAC should
// be added. // be added.
return o.OnionObfuscator.Obfuscate(true, b.Bytes()), nil return o.EncryptError(true, b.Bytes()), nil
} }
// BackwardObfuscate wraps an already encrypted opaque reason error in an // IntermediateEncrypt wraps an already encrypted opaque reason error in an
// additional layer of onion encryption. This process repeats until the error // additional layer of onion encryption. This process repeats until the error
// arrives at the source of the payment. We re-encrypt the message on the // arrives at the source of the payment. We re-encrypt the message on the
// backwards path to ensure that the error is indistinguishable from any other // backwards path to ensure that the error is indistinguishable from any other
// error seen. // error seen.
// //
// NOTE: Part of the Obfuscator interface. // NOTE: Part of the ErrorEncrypter interface.
func (o *FailureObfuscator) BackwardObfuscate(reason lnwire.OpaqueReason) lnwire.OpaqueReason { func (s *SphinxErrorEncrypter) IntermediateEncrypt(reason lnwire.OpaqueReason) lnwire.OpaqueReason {
return o.OnionObfuscator.Obfuscate(false, reason) return s.EncryptError(false, reason)
} }
// A compile time check to ensure FailureObfuscator implements the Obfuscator // A compile time check to ensure SphinxErrorEncrypter implements the
// interface. // ErrorEncrypter interface.
var _ Obfuscator = (*FailureObfuscator)(nil) var _ ErrorEncrypter = (*SphinxErrorEncrypter)(nil)
// FailureDeobfuscator wraps the sphinx data obfuscator and adds awareness of // SphinxErrorDecrypter wraps the sphinx data SphinxErrorDecrypter and maps the
// the lnwire onion failure messages to it. // returned errors to concrete lnwire.FailureMessage instances.
type FailureDeobfuscator struct { type SphinxErrorDecrypter struct {
*sphinx.OnionDeobfuscator *sphinx.OnionErrorDecrypter
} }
// Deobfuscate peels off each layer of onion encryption from the first hop, to // DecryptError peels off each layer of onion encryption from the first hop, to
// the source of the error. A fully populated lnwire.FailureMessage is // the source of the error. A fully populated lnwire.FailureMessage is returned
// returned. // along with the source of the error.
// //
// NOTE: Part of the Obfuscator interface. // NOTE: Part of the ErrorDecrypter interface.
func (o *FailureDeobfuscator) Deobfuscate(reason lnwire.OpaqueReason) (lnwire.FailureMessage, error) { func (s *SphinxErrorDecrypter) DecryptError(reason lnwire.OpaqueReason) (*ForwardingError, error) {
_, failureData, err := o.OnionDeobfuscator.Deobfuscate(reason) source, failureData, err := s.OnionErrorDecrypter.DecryptError(reason)
if err != nil { if err != nil {
return nil, err return nil, err
} }
r := bytes.NewReader(failureData) r := bytes.NewReader(failureData)
return lnwire.DecodeFailure(r, 0) failureMsg, err := lnwire.DecodeFailure(r, 0)
if err != nil {
return nil, err
}
return &ForwardingError{
ErrorSource: source,
FailureMessage: failureMsg,
}, nil
} }
// A compile time check to ensure FailureDeobfuscator implements the // A compile time check to ensure ErrorDecrypter implements the Deobfuscator
// Deobfuscator interface. // interface.
var _ Deobfuscator = (*FailureDeobfuscator)(nil) var _ ErrorDecrypter = (*SphinxErrorDecrypter)(nil)

@ -198,11 +198,13 @@ func (p *OnionProcessor) DecodeHopIterator(r io.Reader, rHash []byte) (HopIterat
}, lnwire.CodeNone }, lnwire.CodeNone
} }
// DecodeOnionObfuscator takes an io.Reader which should contain the onion // ExtractErrorEncrypter takes an io.Reader which should contain the onion
// packet as original received by a forwarding node and creates an Obfuscator // packet as original received by a forwarding node and creates an
// instance using the derived shared secret. In the case that en error occurs, // ErrorEncrypter instance using the derived shared secret. In the case that en
// a lnwire failure code detailing the parsing failure will be returned. // error occurs, a lnwire failure code detailing the parsing failure will be
func (p *OnionProcessor) DecodeOnionObfuscator(r io.Reader) (Obfuscator, lnwire.FailCode) { // returned.
func (p *OnionProcessor) ExtractErrorEncrypter(r io.Reader) (ErrorEncrypter, lnwire.FailCode) {
onionPkt := &sphinx.OnionPacket{} onionPkt := &sphinx.OnionPacket{}
if err := onionPkt.Decode(r); err != nil { if err := onionPkt.Decode(r); err != nil {
switch err { switch err {
@ -215,7 +217,7 @@ func (p *OnionProcessor) DecodeOnionObfuscator(r io.Reader) (Obfuscator, lnwire.
} }
} }
onionObfuscator, err := sphinx.NewOnionObfuscator(p.router, onionObfuscator, err := sphinx.NewOnionErrorEncrypter(p.router,
onionPkt.EphemeralKey) onionPkt.EphemeralKey)
if err != nil { if err != nil {
switch err { switch err {
@ -230,7 +232,7 @@ func (p *OnionProcessor) DecodeOnionObfuscator(r io.Reader) (Obfuscator, lnwire.
} }
} }
return &FailureObfuscator{ return &SphinxErrorEncrypter{
OnionObfuscator: onionObfuscator, OnionErrorEncrypter: onionObfuscator,
}, lnwire.CodeNone }, lnwire.CodeNone
} }

@ -103,7 +103,7 @@ type ChannelLinkConfig struct {
// DecodeOnionObfuscator function is responsible for decoding HTLC // DecodeOnionObfuscator function is responsible for decoding HTLC
// Sphinx onion blob, and creating onion failure obfuscator. // Sphinx onion blob, and creating onion failure obfuscator.
DecodeOnionObfuscator func(r io.Reader) (Obfuscator, lnwire.FailCode) DecodeOnionObfuscator func(r io.Reader) (ErrorEncrypter, lnwire.FailCode)
// GetLastChannelUpdate retrieves the latest routing policy for this // GetLastChannelUpdate retrieves the latest routing policy for this
// particular channel. This will be used to provide payment senders our // particular channel. This will be used to provide payment senders our
@ -570,7 +570,7 @@ func (l *channelLink) handleDownStreamPkt(pkt *htlcPacket, isReProcess bool) {
// Otherwise, we'll send back a proper failure // Otherwise, we'll send back a proper failure
// message. // message.
default: default:
reason, err = obfuscator.InitialObfuscate(failure) reason, err = obfuscator.EncryptFirstHop(failure)
if err != nil { if err != nil {
log.Errorf("unable to obfuscate error: %v", err) log.Errorf("unable to obfuscate error: %v", err)
return return
@ -1461,8 +1461,9 @@ func (l *channelLink) processLockedInHtlcs(
// sendHTLCError functions cancels HTLC and send cancel message back to the // sendHTLCError functions cancels HTLC and send cancel message back to the
// peer from which HTLC was received. // peer from which HTLC was received.
func (l *channelLink) sendHTLCError(rHash [32]byte, failure lnwire.FailureMessage, func (l *channelLink) sendHTLCError(rHash [32]byte, failure lnwire.FailureMessage,
obfuscator Obfuscator) { e ErrorEncrypter) {
reason, err := obfuscator.InitialObfuscate(failure)
reason, err := e.EncryptFirstHop(failure)
if err != nil { if err != nil {
log.Errorf("unable to obfuscate error: %v", err) log.Errorf("unable to obfuscate error: %v", err)
return return

@ -153,11 +153,11 @@ var _ HopIterator = (*mockHopIterator)(nil)
// encodes the failure and do not makes any onion obfuscation. // encodes the failure and do not makes any onion obfuscation.
type mockObfuscator struct{} type mockObfuscator struct{}
func newMockObfuscator() Obfuscator { func newMockObfuscator() ErrorEncrypter {
return &mockObfuscator{} return &mockObfuscator{}
} }
func (o *mockObfuscator) InitialObfuscate(failure lnwire.FailureMessage) ( func (o *mockObfuscator) EncryptFirstHop(failure lnwire.FailureMessage) (
lnwire.OpaqueReason, error) { lnwire.OpaqueReason, error) {
var b bytes.Buffer var b bytes.Buffer
@ -167,7 +167,7 @@ func (o *mockObfuscator) InitialObfuscate(failure lnwire.FailureMessage) (
return b.Bytes(), nil return b.Bytes(), nil
} }
func (o *mockObfuscator) BackwardObfuscate(reason lnwire.OpaqueReason) lnwire.OpaqueReason { func (o *mockObfuscator) IntermediateEncrypt(reason lnwire.OpaqueReason) lnwire.OpaqueReason {
return reason return reason
} }
@ -176,21 +176,24 @@ func (o *mockObfuscator) BackwardObfuscate(reason lnwire.OpaqueReason) lnwire.Op
// only decodes the failure do not makes any onion obfuscation. // only decodes the failure do not makes any onion obfuscation.
type mockDeobfuscator struct{} type mockDeobfuscator struct{}
func newMockDeobfuscator() Deobfuscator { func newMockDeobfuscator() ErrorDecrypter {
return &mockDeobfuscator{} return &mockDeobfuscator{}
} }
func (o *mockDeobfuscator) Deobfuscate(reason lnwire.OpaqueReason) (lnwire.FailureMessage, func (o *mockDeobfuscator) DecryptError(reason lnwire.OpaqueReason) (*ForwardingError, error) {
error) {
r := bytes.NewReader(reason) r := bytes.NewReader(reason)
failure, err := lnwire.DecodeFailure(r, 0) failure, err := lnwire.DecodeFailure(r, 0)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return failure, nil
return &ForwardingError{
FailureMessage: failure,
}, nil
} }
var _ Deobfuscator = (*mockDeobfuscator)(nil) var _ ErrorDecrypter = (*mockDeobfuscator)(nil)
// mockIteratorDecoder test version of hop iterator decoder which decodes the // mockIteratorDecoder test version of hop iterator decoder which decodes the
// encoded array of hops. // encoded array of hops.

@ -35,10 +35,7 @@ type htlcPacket struct {
// obfuscator contains the necessary state to allow the switch to wrap // obfuscator contains the necessary state to allow the switch to wrap
// any forwarded errors in an additional layer of encryption. // any forwarded errors in an additional layer of encryption.
// obfuscator ErrorEncrypter
// TODO(andrew.shvv) revisit after refactoring the way of returning
// errors inside the htlcswitch packet.
obfuscator Obfuscator
// isObfuscated is set to true if an error occurs as soon as the switch // isObfuscated is set to true if an error occurs as soon as the switch
// forwards a packet to the link. If so, and this is an error packet, // forwards a packet to the link. If so, and this is an error packet,
@ -61,13 +58,13 @@ func newInitPacket(destNode [33]byte, htlc *lnwire.UpdateAddHTLC) *htlcPacket {
// newAddPacket creates htlc switch add packet which encapsulates the add htlc // newAddPacket creates htlc switch add packet which encapsulates the add htlc
// request and additional information for proper forwarding over htlc switch. // request and additional information for proper forwarding over htlc switch.
func newAddPacket(src, dest lnwire.ShortChannelID, func newAddPacket(src, dest lnwire.ShortChannelID,
htlc *lnwire.UpdateAddHTLC, obfuscator Obfuscator) *htlcPacket { htlc *lnwire.UpdateAddHTLC, e ErrorEncrypter) *htlcPacket {
return &htlcPacket{ return &htlcPacket{
dest: dest, dest: dest,
src: src, src: src,
htlc: htlc, htlc: htlc,
obfuscator: obfuscator, obfuscator: e,
} }
} }

@ -40,7 +40,7 @@ type pendingPayment struct {
// deobfuscator is an serializable entity which is used if we received // deobfuscator is an serializable entity which is used if we received
// an error, it deobfuscates the onion failure blob, and extracts the // an error, it deobfuscates the onion failure blob, and extracts the
// exact error from it. // exact error from it.
deobfuscator Deobfuscator deobfuscator ErrorDecrypter
} }
// plexPacket encapsulates switch packet and adds error channel to receive // plexPacket encapsulates switch packet and adds error channel to receive
@ -170,7 +170,7 @@ func New(cfg Config) *Switch {
// SendHTLC is used by other subsystems which aren't belong to htlc switch // SendHTLC is used by other subsystems which aren't belong to htlc switch
// package in order to send the htlc update. // package in order to send the htlc update.
func (s *Switch) SendHTLC(nextNode [33]byte, htlc *lnwire.UpdateAddHTLC, func (s *Switch) SendHTLC(nextNode [33]byte, htlc *lnwire.UpdateAddHTLC,
deobfuscator Deobfuscator) ([sha256.Size]byte, error) { deobfuscator ErrorDecrypter) ([sha256.Size]byte, error) {
// Create payment and add to the map of payment in order later to be // Create payment and add to the map of payment in order later to be
// able to retrieve it and return response to the user. // able to retrieve it and return response to the user.
@ -391,7 +391,7 @@ func (s *Switch) handleLocalDispatch(payment *pendingPayment, packet *htlcPacket
// We'll attempt to fully decrypt the onion encrypted error. If // We'll attempt to fully decrypt the onion encrypted error. If
// we're unable to then we'll bail early. // we're unable to then we'll bail early.
failure, err := payment.deobfuscator.Deobfuscate(htlc.Reason) failure, err := payment.deobfuscator.DecryptError(htlc.Reason)
if err != nil { if err != nil {
// TODO(roasbeef): can happen in case of local error in // TODO(roasbeef): can happen in case of local error in
// link pkt handling // link pkt handling
@ -442,7 +442,7 @@ func (s *Switch) handlePacketForward(packet *htlcPacket) error {
// than we should notify this link that some error // than we should notify this link that some error
// occurred. // occurred.
failure := lnwire.FailUnknownNextPeer{} failure := lnwire.FailUnknownNextPeer{}
reason, err := packet.obfuscator.InitialObfuscate(failure) reason, err := packet.obfuscator.EncryptFirstHop(failure)
if err != nil { if err != nil {
err := errors.Errorf("unable to obfuscate "+ err := errors.Errorf("unable to obfuscate "+
"error: %v", err) "error: %v", err)
@ -482,7 +482,7 @@ func (s *Switch) handlePacketForward(packet *htlcPacket) error {
// channel link than we should notify this // channel link than we should notify this
// link that some error occurred. // link that some error occurred.
failure := lnwire.NewTemporaryChannelFailure(nil) failure := lnwire.NewTemporaryChannelFailure(nil)
reason, err := packet.obfuscator.InitialObfuscate(failure) reason, err := packet.obfuscator.EncryptFirstHop(failure)
if err != nil { if err != nil {
err := errors.Errorf("unable to obfuscate "+ err := errors.Errorf("unable to obfuscate "+
"error: %v", err) "error: %v", err)
@ -516,7 +516,7 @@ func (s *Switch) handlePacketForward(packet *htlcPacket) error {
packet.obfuscator, packet.obfuscator,
)); err != nil { )); err != nil {
failure := lnwire.NewTemporaryChannelFailure(nil) failure := lnwire.NewTemporaryChannelFailure(nil)
reason, err := packet.obfuscator.InitialObfuscate(failure) reason, err := packet.obfuscator.EncryptFirstHop(failure)
if err != nil { if err != nil {
err := errors.Errorf("unable to obfuscate "+ err := errors.Errorf("unable to obfuscate "+
"error: %v", err) "error: %v", err)
@ -558,7 +558,7 @@ func (s *Switch) handlePacketForward(packet *htlcPacket) error {
// If this is failure than we need to obfuscate the error. // If this is failure than we need to obfuscate the error.
if htlc, ok := htlc.(*lnwire.UpdateFailHTLC); ok && !packet.isObfuscated { if htlc, ok := htlc.(*lnwire.UpdateFailHTLC); ok && !packet.isObfuscated {
htlc.Reason = circuit.Obfuscator.BackwardObfuscate( htlc.Reason = circuit.ErrorEncrypter.IntermediateEncrypt(
htlc.Reason, htlc.Reason,
) )
} }

@ -352,7 +352,7 @@ func TestSwitchSendPayment(t *testing.T) {
// back. This request should be forwarded back to alice channel link. // back. This request should be forwarded back to alice channel link.
obfuscator := newMockObfuscator() obfuscator := newMockObfuscator()
failure := lnwire.FailIncorrectPaymentAmount{} failure := lnwire.FailIncorrectPaymentAmount{}
reason, err := obfuscator.InitialObfuscate(failure) reason, err := obfuscator.EncryptFirstHop(failure)
if err != nil { if err != nil {
t.Fatalf("unable obfuscate failure: %v", err) t.Fatalf("unable obfuscate failure: %v", err)
} }

@ -556,7 +556,7 @@ func newThreeHopNetwork(t *testing.T, aliceToBob,
Peer: bobServer, Peer: bobServer,
Switch: aliceServer.htlcSwitch, Switch: aliceServer.htlcSwitch,
DecodeHopIterator: decoder.DecodeHopIterator, DecodeHopIterator: decoder.DecodeHopIterator,
DecodeOnionObfuscator: func(io.Reader) (Obfuscator, DecodeOnionObfuscator: func(io.Reader) (ErrorEncrypter,
lnwire.FailCode) { lnwire.FailCode) {
return obfuscator, lnwire.CodeNone return obfuscator, lnwire.CodeNone
}, },
@ -577,7 +577,7 @@ func newThreeHopNetwork(t *testing.T, aliceToBob,
Peer: aliceServer, Peer: aliceServer,
Switch: bobServer.htlcSwitch, Switch: bobServer.htlcSwitch,
DecodeHopIterator: decoder.DecodeHopIterator, DecodeHopIterator: decoder.DecodeHopIterator,
DecodeOnionObfuscator: func(io.Reader) (Obfuscator, DecodeOnionObfuscator: func(io.Reader) (ErrorEncrypter,
lnwire.FailCode) { lnwire.FailCode) {
return obfuscator, lnwire.CodeNone return obfuscator, lnwire.CodeNone
}, },
@ -598,7 +598,7 @@ func newThreeHopNetwork(t *testing.T, aliceToBob,
Peer: carolServer, Peer: carolServer,
Switch: bobServer.htlcSwitch, Switch: bobServer.htlcSwitch,
DecodeHopIterator: decoder.DecodeHopIterator, DecodeHopIterator: decoder.DecodeHopIterator,
DecodeOnionObfuscator: func(io.Reader) (Obfuscator, DecodeOnionObfuscator: func(io.Reader) (ErrorEncrypter,
lnwire.FailCode) { lnwire.FailCode) {
return obfuscator, lnwire.CodeNone return obfuscator, lnwire.CodeNone
}, },
@ -619,7 +619,7 @@ func newThreeHopNetwork(t *testing.T, aliceToBob,
Peer: bobServer, Peer: bobServer,
Switch: carolServer.htlcSwitch, Switch: carolServer.htlcSwitch,
DecodeHopIterator: decoder.DecodeHopIterator, DecodeHopIterator: decoder.DecodeHopIterator,
DecodeOnionObfuscator: func(io.Reader) (Obfuscator, DecodeOnionObfuscator: func(io.Reader) (ErrorEncrypter,
lnwire.FailCode) { lnwire.FailCode) {
return obfuscator, lnwire.CodeNone return obfuscator, lnwire.CodeNone
}, },