mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 01:43:16 +01:00
htlcswitch: move hop iterator into htlcswitch/hop package
Prepares for onion blob decoding outside of htlcswitch.
This commit is contained in:
parent
fb565bcd5d
commit
e54b24289f
@ -5,6 +5,7 @@ import (
|
||||
"io"
|
||||
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch/hop"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
@ -51,7 +52,7 @@ type PaymentCircuit struct {
|
||||
|
||||
// ErrorEncrypter is used to re-encrypt the onion failure before
|
||||
// sending it back to the originator of the payment.
|
||||
ErrorEncrypter ErrorEncrypter
|
||||
ErrorEncrypter hop.ErrorEncrypter
|
||||
|
||||
// LoadedFromDisk is set true for any circuits loaded after the circuit
|
||||
// map is reloaded from disk.
|
||||
@ -136,7 +137,7 @@ func (c *PaymentCircuit) Encode(w io.Writer) error {
|
||||
}
|
||||
|
||||
// Defaults to EncrypterTypeNone.
|
||||
var encrypterType EncrypterType
|
||||
var encrypterType hop.EncrypterType
|
||||
if c.ErrorEncrypter != nil {
|
||||
encrypterType = c.ErrorEncrypter.Type()
|
||||
}
|
||||
@ -147,7 +148,7 @@ func (c *PaymentCircuit) Encode(w io.Writer) error {
|
||||
}
|
||||
|
||||
// Skip encoding of error encrypter if this half add does not have one.
|
||||
if encrypterType == EncrypterTypeNone {
|
||||
if encrypterType == hop.EncrypterTypeNone {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -183,23 +184,23 @@ func (c *PaymentCircuit) Decode(r io.Reader) error {
|
||||
binary.BigEndian.Uint64(scratch[:]))
|
||||
|
||||
// Read the encrypter type used for this circuit.
|
||||
var encrypterType EncrypterType
|
||||
var encrypterType hop.EncrypterType
|
||||
err := binary.Read(r, binary.BigEndian, &encrypterType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch encrypterType {
|
||||
case EncrypterTypeNone:
|
||||
case hop.EncrypterTypeNone:
|
||||
// No encrypter was provided, such as when the payment is
|
||||
// locally initiated.
|
||||
return nil
|
||||
|
||||
case EncrypterTypeSphinx:
|
||||
case hop.EncrypterTypeSphinx:
|
||||
// Sphinx encrypter was used as this is a forwarded HTLC.
|
||||
c.ErrorEncrypter = NewSphinxErrorEncrypter()
|
||||
c.ErrorEncrypter = hop.NewSphinxErrorEncrypter()
|
||||
|
||||
case EncrypterTypeMock:
|
||||
case hop.EncrypterTypeMock:
|
||||
// Test encrypter.
|
||||
c.ErrorEncrypter = NewMockObfuscator()
|
||||
|
||||
|
@ -179,7 +179,7 @@ type CircuitMapConfig struct {
|
||||
|
||||
// ExtractErrorEncrypter derives the shared secret used to encrypt
|
||||
// errors from the obfuscator's ephemeral public key.
|
||||
ExtractErrorEncrypter ErrorEncrypterExtracter
|
||||
ExtractErrorEncrypter hop.ErrorEncrypterExtracter
|
||||
}
|
||||
|
||||
// NewCircuitMap creates a new instance of the circuitMap.
|
||||
|
@ -9,9 +9,10 @@ import (
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
bitcoinCfg "github.com/btcsuite/btcd/chaincfg"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/lightningnetwork/lightning-onion"
|
||||
sphinx "github.com/lightningnetwork/lightning-onion"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch/hop"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
@ -30,7 +31,7 @@ var (
|
||||
|
||||
// testExtracter is a precomputed extraction of testEphemeralKey, using
|
||||
// the sphinxPrivKey.
|
||||
testExtracter *htlcswitch.SphinxErrorEncrypter
|
||||
testExtracter *hop.SphinxErrorEncrypter
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -67,7 +68,7 @@ func initTestExtracter() {
|
||||
testEphemeralKey,
|
||||
)
|
||||
|
||||
sphinxExtracter, ok := obfuscator.(*htlcswitch.SphinxErrorEncrypter)
|
||||
sphinxExtracter, ok := obfuscator.(*hop.SphinxErrorEncrypter)
|
||||
if !ok {
|
||||
panic("did not extract sphinx error encrypter")
|
||||
}
|
||||
@ -81,7 +82,7 @@ func initTestExtracter() {
|
||||
|
||||
// newOnionProcessor creates starts a new htlcswitch.OnionProcessor using a temp
|
||||
// db and no garbage collection.
|
||||
func newOnionProcessor(t *testing.T) *htlcswitch.OnionProcessor {
|
||||
func newOnionProcessor(t *testing.T) *hop.OnionProcessor {
|
||||
sphinxRouter := sphinx.NewRouter(
|
||||
sphinxPrivKey, &bitcoinCfg.SimNetParams, sphinx.NewMemoryReplayLog(),
|
||||
)
|
||||
@ -90,7 +91,7 @@ func newOnionProcessor(t *testing.T) *htlcswitch.OnionProcessor {
|
||||
t.Fatalf("unable to start sphinx router: %v", err)
|
||||
}
|
||||
|
||||
return htlcswitch.NewOnionProcessor(sphinxRouter)
|
||||
return hop.NewOnionProcessor(sphinxRouter)
|
||||
}
|
||||
|
||||
// newCircuitMap creates a new htlcswitch.CircuitMap using a temp db and a
|
||||
@ -128,7 +129,7 @@ var halfCircuitTests = []struct {
|
||||
outValue btcutil.Amount
|
||||
chanID lnwire.ShortChannelID
|
||||
htlcID uint64
|
||||
encrypter htlcswitch.ErrorEncrypter
|
||||
encrypter hop.ErrorEncrypter
|
||||
}{
|
||||
{
|
||||
hash: hash1,
|
||||
@ -1142,7 +1143,7 @@ func TestCircuitMapCloseOpenCircuits(t *testing.T) {
|
||||
ChanID: chan1,
|
||||
HtlcID: 3,
|
||||
},
|
||||
ErrorEncrypter: &htlcswitch.SphinxErrorEncrypter{
|
||||
ErrorEncrypter: &hop.SphinxErrorEncrypter{
|
||||
EphemeralKey: testEphemeralKey,
|
||||
},
|
||||
}
|
||||
|
@ -3,10 +3,9 @@ package htlcswitch
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
sphinx "github.com/lightningnetwork/lightning-onion"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch/hop"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
@ -47,203 +46,15 @@ type ErrorDecrypter interface {
|
||||
DecryptError(lnwire.OpaqueReason) (*ForwardingError, error)
|
||||
}
|
||||
|
||||
// EncrypterType establishes an enum used in serialization to indicate how to
|
||||
// decode a concrete instance of the ErrorEncrypter interface.
|
||||
type EncrypterType byte
|
||||
|
||||
const (
|
||||
// EncrypterTypeNone signals that no error encyrpter is present, this
|
||||
// can happen if the htlc is originates in the switch.
|
||||
EncrypterTypeNone EncrypterType = 0
|
||||
|
||||
// EncrypterTypeSphinx is used to identify a sphinx onion error
|
||||
// encrypter instance.
|
||||
EncrypterTypeSphinx = 1
|
||||
|
||||
// EncrypterTypeMock is used to identify a mock obfuscator instance.
|
||||
EncrypterTypeMock = 2
|
||||
)
|
||||
|
||||
// UnknownEncrypterType is an error message used to signal that an unexpected
|
||||
// EncrypterType was encountered during decoding.
|
||||
type UnknownEncrypterType EncrypterType
|
||||
type UnknownEncrypterType hop.EncrypterType
|
||||
|
||||
// Error returns a formatted error indicating the invalid EncrypterType.
|
||||
func (e UnknownEncrypterType) Error() string {
|
||||
return fmt.Sprintf("unknown error encrypter type: %d", e)
|
||||
}
|
||||
|
||||
// ErrorEncrypterExtracter defines a function signature that extracts an
|
||||
// ErrorEncrypter from an sphinx OnionPacket.
|
||||
type ErrorEncrypterExtracter func(*btcec.PublicKey) (ErrorEncrypter,
|
||||
lnwire.FailCode)
|
||||
|
||||
// ErrorEncrypter is an interface that is used to encrypt HTLC related errors
|
||||
// at the source of the error, and also at each intermediate hop all the way
|
||||
// back to the source of the payment.
|
||||
type ErrorEncrypter interface {
|
||||
// EncryptFirstHop transforms a concrete failure message into an
|
||||
// encrypted opaque failure reason. This method will be used at the
|
||||
// source that the error occurs. It differs from IntermediateEncrypt
|
||||
// slightly, in that it computes a proper MAC over the error.
|
||||
EncryptFirstHop(lnwire.FailureMessage) (lnwire.OpaqueReason, error)
|
||||
|
||||
// EncryptMalformedError is similar to EncryptFirstHop (it adds the
|
||||
// MAC), but it accepts an opaque failure reason rather than a failure
|
||||
// message. This method is used when we receive an
|
||||
// UpdateFailMalformedHTLC from the remote peer and then need to
|
||||
// convert that into a proper error from only the raw bytes.
|
||||
EncryptMalformedError(lnwire.OpaqueReason) lnwire.OpaqueReason
|
||||
|
||||
// IntermediateEncrypt wraps an already encrypted opaque reason error
|
||||
// in an additional layer of onion encryption. This process repeats
|
||||
// until the error arrives at the source of the payment.
|
||||
IntermediateEncrypt(lnwire.OpaqueReason) lnwire.OpaqueReason
|
||||
|
||||
// Type returns an enum indicating the underlying concrete instance
|
||||
// backing this interface.
|
||||
Type() EncrypterType
|
||||
|
||||
// Encode serializes the encrypter's ephemeral public key to the given
|
||||
// io.Writer.
|
||||
Encode(io.Writer) error
|
||||
|
||||
// Decode deserializes the encrypter' ephemeral public key from the
|
||||
// given io.Reader.
|
||||
Decode(io.Reader) error
|
||||
|
||||
// Reextract rederives the encrypter using the extracter, performing an
|
||||
// ECDH with the sphinx router's key and the ephemeral public key.
|
||||
//
|
||||
// NOTE: This should be called shortly after Decode to properly
|
||||
// reinitialize the error encrypter.
|
||||
Reextract(ErrorEncrypterExtracter) error
|
||||
}
|
||||
|
||||
// SphinxErrorEncrypter is a concrete implementation of both the ErrorEncrypter
|
||||
// interface backed by an implementation of the Sphinx packet format. As a
|
||||
// result, all errors handled are themselves wrapped in layers of onion
|
||||
// encryption and must be treated as such accordingly.
|
||||
type SphinxErrorEncrypter struct {
|
||||
*sphinx.OnionErrorEncrypter
|
||||
|
||||
EphemeralKey *btcec.PublicKey
|
||||
}
|
||||
|
||||
// NewSphinxErrorEncrypter initializes a blank sphinx error encrypter, that
|
||||
// should be used to deserialize an encoded SphinxErrorEncrypter. Since the
|
||||
// actual encrypter is not stored in plaintext while at rest, reconstructing the
|
||||
// error encrypter requires:
|
||||
// 1) Decode: to deserialize the ephemeral public key.
|
||||
// 2) Reextract: to "unlock" the actual error encrypter using an active
|
||||
// OnionProcessor.
|
||||
func NewSphinxErrorEncrypter() *SphinxErrorEncrypter {
|
||||
return &SphinxErrorEncrypter{
|
||||
OnionErrorEncrypter: nil,
|
||||
EphemeralKey: &btcec.PublicKey{},
|
||||
}
|
||||
}
|
||||
|
||||
// EncryptFirstHop transforms a concrete failure message into an encrypted
|
||||
// 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
|
||||
// proper MAC over the error.
|
||||
//
|
||||
// NOTE: Part of the ErrorEncrypter interface.
|
||||
func (s *SphinxErrorEncrypter) EncryptFirstHop(failure lnwire.FailureMessage) (lnwire.OpaqueReason, error) {
|
||||
var b bytes.Buffer
|
||||
if err := lnwire.EncodeFailure(&b, failure, 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// We pass a true as the first parameter to indicate that a MAC should
|
||||
// be added.
|
||||
return s.EncryptError(true, b.Bytes()), nil
|
||||
}
|
||||
|
||||
// EncryptMalformedError is similar to EncryptFirstHop (it adds the MAC), but
|
||||
// it accepts an opaque failure reason rather than a failure message. This
|
||||
// method is used when we receive an UpdateFailMalformedHTLC from the remote
|
||||
// peer and then need to convert that into an proper error from only the raw
|
||||
// bytes.
|
||||
//
|
||||
// NOTE: Part of the ErrorEncrypter interface.
|
||||
func (s *SphinxErrorEncrypter) EncryptMalformedError(reason lnwire.OpaqueReason) lnwire.OpaqueReason {
|
||||
return s.EncryptError(true, reason)
|
||||
}
|
||||
|
||||
// IntermediateEncrypt wraps an already encrypted opaque reason error in an
|
||||
// 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
|
||||
// backwards path to ensure that the error is indistinguishable from any other
|
||||
// error seen.
|
||||
//
|
||||
// NOTE: Part of the ErrorEncrypter interface.
|
||||
func (s *SphinxErrorEncrypter) IntermediateEncrypt(reason lnwire.OpaqueReason) lnwire.OpaqueReason {
|
||||
return s.EncryptError(false, reason)
|
||||
}
|
||||
|
||||
// Type returns the identifier for a sphinx error encrypter.
|
||||
func (s *SphinxErrorEncrypter) Type() EncrypterType {
|
||||
return EncrypterTypeSphinx
|
||||
}
|
||||
|
||||
// Encode serializes the error encrypter' ephemeral public key to the provided
|
||||
// io.Writer.
|
||||
func (s *SphinxErrorEncrypter) Encode(w io.Writer) error {
|
||||
ephemeral := s.EphemeralKey.SerializeCompressed()
|
||||
_, err := w.Write(ephemeral)
|
||||
return err
|
||||
}
|
||||
|
||||
// Decode reconstructs the error encrypter's ephemeral public key from the
|
||||
// provided io.Reader.
|
||||
func (s *SphinxErrorEncrypter) Decode(r io.Reader) error {
|
||||
var ephemeral [33]byte
|
||||
if _, err := io.ReadFull(r, ephemeral[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var err error
|
||||
s.EphemeralKey, err = btcec.ParsePubKey(ephemeral[:], btcec.S256())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Reextract rederives the error encrypter from the currently held EphemeralKey.
|
||||
// This intended to be used shortly after Decode, to fully initialize a
|
||||
// SphinxErrorEncrypter.
|
||||
func (s *SphinxErrorEncrypter) Reextract(
|
||||
extract ErrorEncrypterExtracter) error {
|
||||
|
||||
obfuscator, failcode := extract(s.EphemeralKey)
|
||||
if failcode != lnwire.CodeNone {
|
||||
// This should never happen, since we already validated that
|
||||
// this obfuscator can be extracted when it was received in the
|
||||
// link.
|
||||
return fmt.Errorf("unable to reconstruct onion "+
|
||||
"obfuscator, got failcode: %d", failcode)
|
||||
}
|
||||
|
||||
sphinxEncrypter, ok := obfuscator.(*SphinxErrorEncrypter)
|
||||
if !ok {
|
||||
return fmt.Errorf("incorrect onion error extracter")
|
||||
}
|
||||
|
||||
// Copy the freshly extracted encrypter.
|
||||
s.OnionErrorEncrypter = sphinxEncrypter.OnionErrorEncrypter
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// A compile time check to ensure SphinxErrorEncrypter implements the
|
||||
// ErrorEncrypter interface.
|
||||
var _ ErrorEncrypter = (*SphinxErrorEncrypter)(nil)
|
||||
|
||||
// OnionErrorDecrypter is the interface that provides onion level error
|
||||
// decryption.
|
||||
type OnionErrorDecrypter interface {
|
||||
|
205
htlcswitch/hop/error_encryptor.go
Normal file
205
htlcswitch/hop/error_encryptor.go
Normal file
@ -0,0 +1,205 @@
|
||||
package hop
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
sphinx "github.com/lightningnetwork/lightning-onion"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// EncrypterType establishes an enum used in serialization to indicate how to
|
||||
// decode a concrete instance of the ErrorEncrypter interface.
|
||||
type EncrypterType byte
|
||||
|
||||
const (
|
||||
// EncrypterTypeNone signals that no error encyrpter is present, this
|
||||
// can happen if the htlc is originates in the switch.
|
||||
EncrypterTypeNone EncrypterType = 0
|
||||
|
||||
// EncrypterTypeSphinx is used to identify a sphinx onion error
|
||||
// encrypter instance.
|
||||
EncrypterTypeSphinx = 1
|
||||
|
||||
// EncrypterTypeMock is used to identify a mock obfuscator instance.
|
||||
EncrypterTypeMock = 2
|
||||
)
|
||||
|
||||
// ErrorEncrypterExtracter defines a function signature that extracts an
|
||||
// ErrorEncrypter from an sphinx OnionPacket.
|
||||
type ErrorEncrypterExtracter func(*btcec.PublicKey) (ErrorEncrypter,
|
||||
lnwire.FailCode)
|
||||
|
||||
// ErrorEncrypter is an interface that is used to encrypt HTLC related errors
|
||||
// at the source of the error, and also at each intermediate hop all the way
|
||||
// back to the source of the payment.
|
||||
type ErrorEncrypter interface {
|
||||
// EncryptFirstHop transforms a concrete failure message into an
|
||||
// encrypted opaque failure reason. This method will be used at the
|
||||
// source that the error occurs. It differs from IntermediateEncrypt
|
||||
// slightly, in that it computes a proper MAC over the error.
|
||||
EncryptFirstHop(lnwire.FailureMessage) (lnwire.OpaqueReason, error)
|
||||
|
||||
// EncryptMalformedError is similar to EncryptFirstHop (it adds the
|
||||
// MAC), but it accepts an opaque failure reason rather than a failure
|
||||
// message. This method is used when we receive an
|
||||
// UpdateFailMalformedHTLC from the remote peer and then need to
|
||||
// convert that into a proper error from only the raw bytes.
|
||||
EncryptMalformedError(lnwire.OpaqueReason) lnwire.OpaqueReason
|
||||
|
||||
// IntermediateEncrypt wraps an already encrypted opaque reason error
|
||||
// in an additional layer of onion encryption. This process repeats
|
||||
// until the error arrives at the source of the payment.
|
||||
IntermediateEncrypt(lnwire.OpaqueReason) lnwire.OpaqueReason
|
||||
|
||||
// Type returns an enum indicating the underlying concrete instance
|
||||
// backing this interface.
|
||||
Type() EncrypterType
|
||||
|
||||
// Encode serializes the encrypter's ephemeral public key to the given
|
||||
// io.Writer.
|
||||
Encode(io.Writer) error
|
||||
|
||||
// Decode deserializes the encrypter' ephemeral public key from the
|
||||
// given io.Reader.
|
||||
Decode(io.Reader) error
|
||||
|
||||
// Reextract rederives the encrypter using the extracter, performing an
|
||||
// ECDH with the sphinx router's key and the ephemeral public key.
|
||||
//
|
||||
// NOTE: This should be called shortly after Decode to properly
|
||||
// reinitialize the error encrypter.
|
||||
Reextract(ErrorEncrypterExtracter) error
|
||||
}
|
||||
|
||||
// SphinxErrorEncrypter is a concrete implementation of both the ErrorEncrypter
|
||||
// interface backed by an implementation of the Sphinx packet format. As a
|
||||
// result, all errors handled are themselves wrapped in layers of onion
|
||||
// encryption and must be treated as such accordingly.
|
||||
type SphinxErrorEncrypter struct {
|
||||
*sphinx.OnionErrorEncrypter
|
||||
|
||||
EphemeralKey *btcec.PublicKey
|
||||
}
|
||||
|
||||
// NewSphinxErrorEncrypter initializes a blank sphinx error encrypter, that
|
||||
// should be used to deserialize an encoded SphinxErrorEncrypter. Since the
|
||||
// actual encrypter is not stored in plaintext while at rest, reconstructing the
|
||||
// error encrypter requires:
|
||||
// 1) Decode: to deserialize the ephemeral public key.
|
||||
// 2) Reextract: to "unlock" the actual error encrypter using an active
|
||||
// OnionProcessor.
|
||||
func NewSphinxErrorEncrypter() *SphinxErrorEncrypter {
|
||||
return &SphinxErrorEncrypter{
|
||||
OnionErrorEncrypter: nil,
|
||||
EphemeralKey: &btcec.PublicKey{},
|
||||
}
|
||||
}
|
||||
|
||||
// EncryptFirstHop transforms a concrete failure message into an encrypted
|
||||
// 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
|
||||
// proper MAC over the error.
|
||||
//
|
||||
// NOTE: Part of the ErrorEncrypter interface.
|
||||
func (s *SphinxErrorEncrypter) EncryptFirstHop(
|
||||
failure lnwire.FailureMessage) (lnwire.OpaqueReason, error) {
|
||||
|
||||
var b bytes.Buffer
|
||||
if err := lnwire.EncodeFailure(&b, failure, 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// We pass a true as the first parameter to indicate that a MAC should
|
||||
// be added.
|
||||
return s.EncryptError(true, b.Bytes()), nil
|
||||
}
|
||||
|
||||
// EncryptMalformedError is similar to EncryptFirstHop (it adds the MAC), but
|
||||
// it accepts an opaque failure reason rather than a failure message. This
|
||||
// method is used when we receive an UpdateFailMalformedHTLC from the remote
|
||||
// peer and then need to convert that into an proper error from only the raw
|
||||
// bytes.
|
||||
//
|
||||
// NOTE: Part of the ErrorEncrypter interface.
|
||||
func (s *SphinxErrorEncrypter) EncryptMalformedError(
|
||||
reason lnwire.OpaqueReason) lnwire.OpaqueReason {
|
||||
|
||||
return s.EncryptError(true, reason)
|
||||
}
|
||||
|
||||
// IntermediateEncrypt wraps an already encrypted opaque reason error in an
|
||||
// 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
|
||||
// backwards path to ensure that the error is indistinguishable from any other
|
||||
// error seen.
|
||||
//
|
||||
// NOTE: Part of the ErrorEncrypter interface.
|
||||
func (s *SphinxErrorEncrypter) IntermediateEncrypt(
|
||||
reason lnwire.OpaqueReason) lnwire.OpaqueReason {
|
||||
|
||||
return s.EncryptError(false, reason)
|
||||
}
|
||||
|
||||
// Type returns the identifier for a sphinx error encrypter.
|
||||
func (s *SphinxErrorEncrypter) Type() EncrypterType {
|
||||
return EncrypterTypeSphinx
|
||||
}
|
||||
|
||||
// Encode serializes the error encrypter' ephemeral public key to the provided
|
||||
// io.Writer.
|
||||
func (s *SphinxErrorEncrypter) Encode(w io.Writer) error {
|
||||
ephemeral := s.EphemeralKey.SerializeCompressed()
|
||||
_, err := w.Write(ephemeral)
|
||||
return err
|
||||
}
|
||||
|
||||
// Decode reconstructs the error encrypter's ephemeral public key from the
|
||||
// provided io.Reader.
|
||||
func (s *SphinxErrorEncrypter) Decode(r io.Reader) error {
|
||||
var ephemeral [33]byte
|
||||
if _, err := io.ReadFull(r, ephemeral[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var err error
|
||||
s.EphemeralKey, err = btcec.ParsePubKey(ephemeral[:], btcec.S256())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Reextract rederives the error encrypter from the currently held EphemeralKey.
|
||||
// This intended to be used shortly after Decode, to fully initialize a
|
||||
// SphinxErrorEncrypter.
|
||||
func (s *SphinxErrorEncrypter) Reextract(
|
||||
extract ErrorEncrypterExtracter) error {
|
||||
|
||||
obfuscator, failcode := extract(s.EphemeralKey)
|
||||
if failcode != lnwire.CodeNone {
|
||||
// This should never happen, since we already validated that
|
||||
// this obfuscator can be extracted when it was received in the
|
||||
// link.
|
||||
return fmt.Errorf("unable to reconstruct onion "+
|
||||
"obfuscator, got failcode: %d", failcode)
|
||||
}
|
||||
|
||||
sphinxEncrypter, ok := obfuscator.(*SphinxErrorEncrypter)
|
||||
if !ok {
|
||||
return fmt.Errorf("incorrect onion error extracter")
|
||||
}
|
||||
|
||||
// Copy the freshly extracted encrypter.
|
||||
s.OnionErrorEncrypter = sphinxEncrypter.OnionErrorEncrypter
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// A compile time check to ensure SphinxErrorEncrypter implements the
|
||||
// ErrorEncrypter interface.
|
||||
var _ ErrorEncrypter = (*SphinxErrorEncrypter)(nil)
|
@ -1,4 +1,4 @@
|
||||
package htlcswitch
|
||||
package hop
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@ -6,23 +6,22 @@ import (
|
||||
"io"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/lightningnetwork/lightning-onion"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch/hop"
|
||||
sphinx "github.com/lightningnetwork/lightning-onion"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// HopIterator is an interface that abstracts away the routing information
|
||||
// Iterator is an interface that abstracts away the routing information
|
||||
// included in HTLC's which includes the entirety of the payment path of an
|
||||
// HTLC. This interface provides two basic method which carry out: how to
|
||||
// interpret the forwarding information encoded within the HTLC packet, and hop
|
||||
// to encode the forwarding information for the _next_ hop.
|
||||
type HopIterator interface {
|
||||
type Iterator interface {
|
||||
// ForwardingInstructions returns the set of fields that detail exactly
|
||||
// _how_ this hop should forward the HTLC to the next hop.
|
||||
// Additionally, the information encoded within the returned
|
||||
// ForwardingInfo is to be used by each hop to authenticate the
|
||||
// information given to it by the prior hop.
|
||||
ForwardingInstructions() (hop.ForwardingInfo, error)
|
||||
ForwardingInstructions() (ForwardingInfo, error)
|
||||
|
||||
// ExtraOnionBlob returns the additional EOB data (if available).
|
||||
ExtraOnionBlob() []byte
|
||||
@ -64,7 +63,7 @@ func makeSphinxHopIterator(ogPacket *sphinx.OnionPacket,
|
||||
|
||||
// A compile time check to ensure sphinxHopIterator implements the HopIterator
|
||||
// interface.
|
||||
var _ HopIterator = (*sphinxHopIterator)(nil)
|
||||
var _ Iterator = (*sphinxHopIterator)(nil)
|
||||
|
||||
// Encode encodes iterator and writes it to the writer.
|
||||
//
|
||||
@ -79,32 +78,30 @@ func (r *sphinxHopIterator) EncodeNextHop(w io.Writer) error {
|
||||
// hop to authenticate the information given to it by the prior hop.
|
||||
//
|
||||
// NOTE: Part of the HopIterator interface.
|
||||
func (r *sphinxHopIterator) ForwardingInstructions() (
|
||||
hop.ForwardingInfo, error) {
|
||||
|
||||
func (r *sphinxHopIterator) ForwardingInstructions() (ForwardingInfo, error) {
|
||||
switch r.processedPacket.Payload.Type {
|
||||
// If this is the legacy payload, then we'll extract the information
|
||||
// directly from the pre-populated ForwardingInstructions field.
|
||||
case sphinx.PayloadLegacy:
|
||||
fwdInst := r.processedPacket.ForwardingInstructions
|
||||
p := hop.NewLegacyPayload(fwdInst)
|
||||
p := NewLegacyPayload(fwdInst)
|
||||
|
||||
return p.ForwardingInfo(), nil
|
||||
|
||||
// Otherwise, if this is the TLV payload, then we'll make a new stream
|
||||
// to decode only what we need to make routing decisions.
|
||||
case sphinx.PayloadTLV:
|
||||
p, err := hop.NewPayloadFromReader(bytes.NewReader(
|
||||
p, err := NewPayloadFromReader(bytes.NewReader(
|
||||
r.processedPacket.Payload.Payload,
|
||||
))
|
||||
if err != nil {
|
||||
return hop.ForwardingInfo{}, err
|
||||
return ForwardingInfo{}, err
|
||||
}
|
||||
|
||||
return p.ForwardingInfo(), nil
|
||||
|
||||
default:
|
||||
return hop.ForwardingInfo{}, fmt.Errorf("unknown "+
|
||||
return ForwardingInfo{}, fmt.Errorf("unknown "+
|
||||
"sphinx payload type: %v",
|
||||
r.processedPacket.Payload.Type)
|
||||
}
|
||||
@ -164,7 +161,7 @@ func (p *OnionProcessor) Stop() error {
|
||||
// instance using the rHash as the associated data when checking the relevant
|
||||
// MACs during the decoding process.
|
||||
func (p *OnionProcessor) DecodeHopIterator(r io.Reader, rHash []byte,
|
||||
incomingCltv uint32) (HopIterator, lnwire.FailCode) {
|
||||
incomingCltv uint32) (Iterator, lnwire.FailCode) {
|
||||
|
||||
onionPkt := &sphinx.OnionPacket{}
|
||||
if err := onionPkt.Decode(r); err != nil {
|
||||
@ -216,7 +213,7 @@ type DecodeHopIteratorRequest struct {
|
||||
// DecodeHopIteratorResponse encapsulates the outcome of a batched sphinx onion
|
||||
// processing.
|
||||
type DecodeHopIteratorResponse struct {
|
||||
HopIterator HopIterator
|
||||
HopIterator Iterator
|
||||
FailCode lnwire.FailCode
|
||||
}
|
||||
|
||||
@ -225,7 +222,7 @@ type DecodeHopIteratorResponse struct {
|
||||
//
|
||||
// NOTE: The HopIterator should be considered invalid if the fail code is
|
||||
// anything but lnwire.CodeNone.
|
||||
func (r *DecodeHopIteratorResponse) Result() (HopIterator, lnwire.FailCode) {
|
||||
func (r *DecodeHopIteratorResponse) Result() (Iterator, lnwire.FailCode) {
|
||||
return r.HopIterator, r.FailCode
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package htlcswitch
|
||||
package hop
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@ -7,7 +7,6 @@ import (
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
sphinx "github.com/lightningnetwork/lightning-onion"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch/hop"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/record"
|
||||
"github.com/lightningnetwork/lnd/tlv"
|
||||
@ -30,7 +29,7 @@ func TestSphinxHopIteratorForwardingInstructions(t *testing.T) {
|
||||
// Next, we'll make the hop forwarding information that we should
|
||||
// extract each type, no matter the payload type.
|
||||
nextAddrInt := binary.BigEndian.Uint64(hopData.NextAddress[:])
|
||||
expectedFwdInfo := hop.ForwardingInfo{
|
||||
expectedFwdInfo := ForwardingInfo{
|
||||
NextHop: lnwire.NewShortChanIDFromInt(nextAddrInt),
|
||||
AmountToForward: lnwire.MilliSatoshi(hopData.ForwardAmount),
|
||||
OutgoingCTLV: hopData.OutgoingCltv,
|
||||
@ -54,7 +53,7 @@ func TestSphinxHopIteratorForwardingInstructions(t *testing.T) {
|
||||
|
||||
var testCases = []struct {
|
||||
sphinxPacket *sphinx.ProcessedPacket
|
||||
expectedFwdInfo hop.ForwardingInfo
|
||||
expectedFwdInfo ForwardingInfo
|
||||
}{
|
||||
// A regular legacy payload that signals more hops.
|
||||
{
|
16
htlcswitch/hop/log.go
Normal file
16
htlcswitch/hop/log.go
Normal file
@ -0,0 +1,16 @@
|
||||
package hop
|
||||
|
||||
import (
|
||||
"github.com/btcsuite/btclog"
|
||||
)
|
||||
|
||||
// log is a logger that is initialized with no output filters. This
|
||||
// means the package will not perform any logging by default until the caller
|
||||
// requests it.
|
||||
var log btclog.Logger
|
||||
|
||||
// UseLogger uses a specified Logger to output package logging info. This
|
||||
// function is called from the parent package htlcswitch logger initialization.
|
||||
func UseLogger(logger btclog.Logger) {
|
||||
log = logger
|
||||
}
|
@ -144,12 +144,12 @@ type ChannelLinkConfig struct {
|
||||
//
|
||||
// NOTE: This function assumes the same set of readers and preimages
|
||||
// are always presented for the same identifier.
|
||||
DecodeHopIterators func([]byte, []DecodeHopIteratorRequest) (
|
||||
[]DecodeHopIteratorResponse, error)
|
||||
DecodeHopIterators func([]byte, []hop.DecodeHopIteratorRequest) (
|
||||
[]hop.DecodeHopIteratorResponse, error)
|
||||
|
||||
// ExtractErrorEncrypter function is responsible for decoding HTLC
|
||||
// Sphinx onion blob, and creating onion failure obfuscator.
|
||||
ExtractErrorEncrypter ErrorEncrypterExtracter
|
||||
ExtractErrorEncrypter hop.ErrorEncrypterExtracter
|
||||
|
||||
// FetchLastChannelUpdate retrieves the latest routing policy for a
|
||||
// target channel. This channel will typically be the outgoing channel
|
||||
@ -379,7 +379,7 @@ type channelLink struct {
|
||||
// hodlHtlc contains htlc data that is required for resolution.
|
||||
type hodlHtlc struct {
|
||||
pd *lnwallet.PaymentDescriptor
|
||||
obfuscator ErrorEncrypter
|
||||
obfuscator hop.ErrorEncrypter
|
||||
}
|
||||
|
||||
// NewChannelLink creates a new instance of a ChannelLink given a configuration
|
||||
@ -2553,7 +2553,9 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
|
||||
l.tracef("processing %d remote adds for height %d",
|
||||
len(lockedInHtlcs), fwdPkg.Height)
|
||||
|
||||
decodeReqs := make([]DecodeHopIteratorRequest, 0, len(lockedInHtlcs))
|
||||
decodeReqs := make(
|
||||
[]hop.DecodeHopIteratorRequest, 0, len(lockedInHtlcs),
|
||||
)
|
||||
for _, pd := range lockedInHtlcs {
|
||||
switch pd.EntryType {
|
||||
|
||||
@ -2565,7 +2567,7 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
|
||||
// which process the Sphinx packet.
|
||||
onionReader := bytes.NewReader(pd.OnionBlob)
|
||||
|
||||
req := DecodeHopIteratorRequest{
|
||||
req := hop.DecodeHopIteratorRequest{
|
||||
OnionReader: onionReader,
|
||||
RHash: pd.RHash[:],
|
||||
IncomingCltv: pd.Timeout,
|
||||
@ -2850,7 +2852,7 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
|
||||
// processExitHop handles an htlc for which this link is the exit hop. It
|
||||
// returns a boolean indicating whether the commitment tx needs an update.
|
||||
func (l *channelLink) processExitHop(pd *lnwallet.PaymentDescriptor,
|
||||
obfuscator ErrorEncrypter, fwdInfo hop.ForwardingInfo,
|
||||
obfuscator hop.ErrorEncrypter, fwdInfo hop.ForwardingInfo,
|
||||
heightNow uint32, eob []byte) (bool, error) {
|
||||
|
||||
// If hodl.ExitSettle is requested, we will not validate the final hop's
|
||||
@ -3021,7 +3023,7 @@ func (l *channelLink) handleBatchFwdErrs(errChan chan error) {
|
||||
// sendHTLCError functions cancels HTLC and send cancel message back to the
|
||||
// peer from which HTLC was received.
|
||||
func (l *channelLink) sendHTLCError(htlcIndex uint64, failure lnwire.FailureMessage,
|
||||
e ErrorEncrypter, sourceRef *channeldb.AddRef) {
|
||||
e hop.ErrorEncrypter, sourceRef *channeldb.AddRef) {
|
||||
|
||||
reason, err := e.EncryptFirstHop(failure)
|
||||
if err != nil {
|
||||
|
@ -1292,7 +1292,7 @@ func TestChannelLinkMultiHopDecodeError(t *testing.T) {
|
||||
|
||||
// Replace decode function with another which throws an error.
|
||||
n.carolChannelLink.cfg.ExtractErrorEncrypter = func(
|
||||
*btcec.PublicKey) (ErrorEncrypter, lnwire.FailCode) {
|
||||
*btcec.PublicKey) (hop.ErrorEncrypter, lnwire.FailCode) {
|
||||
return nil, lnwire.CodeInvalidOnionVersion
|
||||
}
|
||||
|
||||
@ -1666,7 +1666,7 @@ func newSingleLinkTestHarness(chanAmt, chanReserve btcutil.Amount) (
|
||||
ForwardPackets: aliceSwitch.ForwardPackets,
|
||||
DecodeHopIterators: decoder.DecodeHopIterators,
|
||||
ExtractErrorEncrypter: func(*btcec.PublicKey) (
|
||||
ErrorEncrypter, lnwire.FailCode) {
|
||||
hop.ErrorEncrypter, lnwire.FailCode) {
|
||||
return obfuscator, lnwire.CodeNone
|
||||
},
|
||||
FetchLastChannelUpdate: mockGetChanUpdateMessage,
|
||||
@ -4230,7 +4230,7 @@ func (h *persistentLinkHarness) restartLink(
|
||||
ForwardPackets: aliceSwitch.ForwardPackets,
|
||||
DecodeHopIterators: decoder.DecodeHopIterators,
|
||||
ExtractErrorEncrypter: func(*btcec.PublicKey) (
|
||||
ErrorEncrypter, lnwire.FailCode) {
|
||||
hop.ErrorEncrypter, lnwire.FailCode) {
|
||||
return obfuscator, lnwire.CodeNone
|
||||
},
|
||||
FetchLastChannelUpdate: mockGetChanUpdateMessage,
|
||||
|
@ -3,6 +3,7 @@ package htlcswitch
|
||||
import (
|
||||
"github.com/btcsuite/btclog"
|
||||
"github.com/lightningnetwork/lnd/build"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch/hop"
|
||||
)
|
||||
|
||||
// log is a logger that is initialized with no output filters. This
|
||||
@ -12,7 +13,10 @@ var log btclog.Logger
|
||||
|
||||
// The default amount of logging is none.
|
||||
func init() {
|
||||
UseLogger(build.NewSubLogger("HSWC", nil))
|
||||
logger := build.NewSubLogger("HSWC", nil)
|
||||
|
||||
UseLogger(logger)
|
||||
hop.UseLogger(logger)
|
||||
}
|
||||
|
||||
// DisableLog disables all library log output. Logging output is disabled
|
||||
|
@ -272,7 +272,7 @@ type mockHopIterator struct {
|
||||
hops []hop.ForwardingInfo
|
||||
}
|
||||
|
||||
func newMockHopIterator(hops ...hop.ForwardingInfo) HopIterator {
|
||||
func newMockHopIterator(hops ...hop.ForwardingInfo) hop.Iterator {
|
||||
return &mockHopIterator{hops: hops}
|
||||
}
|
||||
|
||||
@ -289,7 +289,8 @@ func (r *mockHopIterator) ExtraOnionBlob() []byte {
|
||||
}
|
||||
|
||||
func (r *mockHopIterator) ExtractErrorEncrypter(
|
||||
extracter ErrorEncrypterExtracter) (ErrorEncrypter, lnwire.FailCode) {
|
||||
extracter hop.ErrorEncrypterExtracter) (hop.ErrorEncrypter,
|
||||
lnwire.FailCode) {
|
||||
|
||||
return extracter(nil)
|
||||
}
|
||||
@ -331,7 +332,7 @@ func encodeFwdInfo(w io.Writer, f *hop.ForwardingInfo) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ HopIterator = (*mockHopIterator)(nil)
|
||||
var _ hop.Iterator = (*mockHopIterator)(nil)
|
||||
|
||||
// mockObfuscator mock implementation of the failure obfuscator which only
|
||||
// encodes the failure and do not makes any onion obfuscation.
|
||||
@ -340,7 +341,7 @@ type mockObfuscator struct {
|
||||
}
|
||||
|
||||
// NewMockObfuscator initializes a dummy mockObfuscator used for testing.
|
||||
func NewMockObfuscator() ErrorEncrypter {
|
||||
func NewMockObfuscator() hop.ErrorEncrypter {
|
||||
return &mockObfuscator{}
|
||||
}
|
||||
|
||||
@ -348,8 +349,8 @@ func (o *mockObfuscator) OnionPacket() *sphinx.OnionPacket {
|
||||
return o.ogPacket
|
||||
}
|
||||
|
||||
func (o *mockObfuscator) Type() EncrypterType {
|
||||
return EncrypterTypeMock
|
||||
func (o *mockObfuscator) Type() hop.EncrypterType {
|
||||
return hop.EncrypterTypeMock
|
||||
}
|
||||
|
||||
func (o *mockObfuscator) Encode(w io.Writer) error {
|
||||
@ -360,7 +361,9 @@ func (o *mockObfuscator) Decode(r io.Reader) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *mockObfuscator) Reextract(extracter ErrorEncrypterExtracter) error {
|
||||
func (o *mockObfuscator) Reextract(
|
||||
extracter hop.ErrorEncrypterExtracter) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -411,19 +414,19 @@ var _ ErrorDecrypter = (*mockDeobfuscator)(nil)
|
||||
type mockIteratorDecoder struct {
|
||||
mu sync.RWMutex
|
||||
|
||||
responses map[[32]byte][]DecodeHopIteratorResponse
|
||||
responses map[[32]byte][]hop.DecodeHopIteratorResponse
|
||||
|
||||
decodeFail bool
|
||||
}
|
||||
|
||||
func newMockIteratorDecoder() *mockIteratorDecoder {
|
||||
return &mockIteratorDecoder{
|
||||
responses: make(map[[32]byte][]DecodeHopIteratorResponse),
|
||||
responses: make(map[[32]byte][]hop.DecodeHopIteratorResponse),
|
||||
}
|
||||
}
|
||||
|
||||
func (p *mockIteratorDecoder) DecodeHopIterator(r io.Reader, rHash []byte,
|
||||
cltv uint32) (HopIterator, lnwire.FailCode) {
|
||||
cltv uint32) (hop.Iterator, lnwire.FailCode) {
|
||||
|
||||
var b [4]byte
|
||||
_, err := r.Read(b[:])
|
||||
@ -446,7 +449,8 @@ func (p *mockIteratorDecoder) DecodeHopIterator(r io.Reader, rHash []byte,
|
||||
}
|
||||
|
||||
func (p *mockIteratorDecoder) DecodeHopIterators(id []byte,
|
||||
reqs []DecodeHopIteratorRequest) ([]DecodeHopIteratorResponse, error) {
|
||||
reqs []hop.DecodeHopIteratorRequest) (
|
||||
[]hop.DecodeHopIteratorResponse, error) {
|
||||
|
||||
idHash := sha256.Sum256(id)
|
||||
|
||||
@ -459,7 +463,7 @@ func (p *mockIteratorDecoder) DecodeHopIterators(id []byte,
|
||||
|
||||
batchSize := len(reqs)
|
||||
|
||||
resps := make([]DecodeHopIteratorResponse, 0, batchSize)
|
||||
resps := make([]hop.DecodeHopIteratorResponse, 0, batchSize)
|
||||
for _, req := range reqs {
|
||||
iterator, failcode := p.DecodeHopIterator(
|
||||
req.OnionReader, req.RHash, req.IncomingCltv,
|
||||
@ -469,7 +473,7 @@ func (p *mockIteratorDecoder) DecodeHopIterators(id []byte,
|
||||
failcode = lnwire.CodeTemporaryChannelFailure
|
||||
}
|
||||
|
||||
resp := DecodeHopIteratorResponse{
|
||||
resp := hop.DecodeHopIteratorResponse{
|
||||
HopIterator: iterator,
|
||||
FailCode: failcode,
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package htlcswitch
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch/hop"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
@ -54,7 +55,7 @@ type htlcPacket struct {
|
||||
|
||||
// obfuscator contains the necessary state to allow the switch to wrap
|
||||
// any forwarded errors in an additional layer of encryption.
|
||||
obfuscator ErrorEncrypter
|
||||
obfuscator hop.ErrorEncrypter
|
||||
|
||||
// localFailure is set to true if an HTLC fails for a local payment before
|
||||
// the first hop. In this case, the failure reason is simply encoded, not
|
||||
|
@ -143,7 +143,7 @@ type Config struct {
|
||||
// ExtractErrorEncrypter is an interface allowing switch to reextract
|
||||
// error encrypters stored in the circuit map on restarts, since they
|
||||
// are not stored directly within the database.
|
||||
ExtractErrorEncrypter ErrorEncrypterExtracter
|
||||
ExtractErrorEncrypter hop.ErrorEncrypterExtracter
|
||||
|
||||
// FetchLastChannelUpdate retrieves the latest routing policy for a
|
||||
// target channel. This channel will typically be the outgoing channel
|
||||
|
@ -1054,7 +1054,7 @@ func createTwoClusterChannels(aliceToBob, bobToCarol btcutil.Amount) (
|
||||
type hopNetwork struct {
|
||||
feeEstimator *mockFeeEstimator
|
||||
globalPolicy ForwardingPolicy
|
||||
obfuscator ErrorEncrypter
|
||||
obfuscator hop.ErrorEncrypter
|
||||
|
||||
defaultDelta uint32
|
||||
}
|
||||
@ -1101,7 +1101,7 @@ func (h *hopNetwork) createChannelLink(server, peer *mockServer,
|
||||
ForwardPackets: server.htlcSwitch.ForwardPackets,
|
||||
DecodeHopIterators: decoder.DecodeHopIterators,
|
||||
ExtractErrorEncrypter: func(*btcec.PublicKey) (
|
||||
ErrorEncrypter, lnwire.FailCode) {
|
||||
hop.ErrorEncrypter, lnwire.FailCode) {
|
||||
return h.obfuscator, lnwire.CodeNone
|
||||
},
|
||||
FetchLastChannelUpdate: mockGetChanUpdateMessage,
|
||||
|
@ -34,6 +34,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/contractcourt"
|
||||
"github.com/lightningnetwork/lnd/discovery"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch/hop"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/invoices"
|
||||
"github.com/lightningnetwork/lnd/lncfg"
|
||||
@ -208,7 +209,7 @@ type server struct {
|
||||
|
||||
chainArb *contractcourt.ChainArbitrator
|
||||
|
||||
sphinx *htlcswitch.OnionProcessor
|
||||
sphinx *hop.OnionProcessor
|
||||
|
||||
towerClient wtclient.Client
|
||||
|
||||
@ -367,7 +368,7 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB,
|
||||
|
||||
// TODO(roasbeef): derive proper onion key based on rotation
|
||||
// schedule
|
||||
sphinx: htlcswitch.NewOnionProcessor(sphinxRouter),
|
||||
sphinx: hop.NewOnionProcessor(sphinxRouter),
|
||||
|
||||
persistentPeers: make(map[string]struct{}),
|
||||
persistentPeersBackoff: make(map[string]time.Duration),
|
||||
|
Loading…
Reference in New Issue
Block a user