routing/router: define PaymentAttemptDispatcher interface
The switch satisfies this interface, and makes it easy to mock the send method from the router.
This commit is contained in:
parent
27ae22fa6c
commit
f1cb54f943
31
routing/mock_test.go
Normal file
31
routing/mock_test.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package routing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
|
|
||||||
|
"github.com/lightningnetwork/lnd/htlcswitch"
|
||||||
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mockPaymentAttemptDispatcher struct {
|
||||||
|
onPayment func(firstHop lnwire.ShortChannelID) ([32]byte, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ PaymentAttemptDispatcher = (*mockPaymentAttemptDispatcher)(nil)
|
||||||
|
|
||||||
|
func (m *mockPaymentAttemptDispatcher) SendHTLC(firstHop lnwire.ShortChannelID,
|
||||||
|
_ *lnwire.UpdateAddHTLC,
|
||||||
|
_ htlcswitch.ErrorDecrypter) ([sha256.Size]byte, error) {
|
||||||
|
|
||||||
|
if m.onPayment != nil {
|
||||||
|
return m.onPayment(firstHop)
|
||||||
|
}
|
||||||
|
|
||||||
|
return [sha256.Size]byte{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockPaymentAttemptDispatcher) setPaymentResult(
|
||||||
|
f func(firstHop lnwire.ShortChannelID) ([32]byte, error)) {
|
||||||
|
|
||||||
|
m.onPayment = f
|
||||||
|
}
|
@ -126,6 +126,18 @@ type ChannelGraphSource interface {
|
|||||||
e1, e2 *channeldb.ChannelEdgePolicy) error) error
|
e1, e2 *channeldb.ChannelEdgePolicy) error) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PaymentAttemptDispatcher is used by the router to send payment attempts onto
|
||||||
|
// the network, and receive their results.
|
||||||
|
type PaymentAttemptDispatcher interface {
|
||||||
|
// SendHTLC is a function that directs a link-layer switch to
|
||||||
|
// forward a fully encoded payment to the first hop in the route
|
||||||
|
// denoted by its public key. A non-nil error is to be returned if the
|
||||||
|
// payment was unsuccessful.
|
||||||
|
SendHTLC(firstHop lnwire.ShortChannelID,
|
||||||
|
htlcAdd *lnwire.UpdateAddHTLC,
|
||||||
|
deobfuscator htlcswitch.ErrorDecrypter) ([sha256.Size]byte, error)
|
||||||
|
}
|
||||||
|
|
||||||
// FeeSchema is the set fee configuration for a Lightning Node on the network.
|
// FeeSchema is the set fee configuration for a Lightning Node on the network.
|
||||||
// Using the coefficients described within the schema, the required fee to
|
// Using the coefficients described within the schema, the required fee to
|
||||||
// forward outgoing payments can be derived.
|
// forward outgoing payments can be derived.
|
||||||
@ -173,13 +185,10 @@ type Config struct {
|
|||||||
// we need in order to properly maintain the channel graph.
|
// we need in order to properly maintain the channel graph.
|
||||||
ChainView chainview.FilteredChainView
|
ChainView chainview.FilteredChainView
|
||||||
|
|
||||||
// SendToSwitch is a function that directs a link-layer switch to
|
// Payer is an instance of a PaymentAttemptDispatcher and is used by
|
||||||
// forward a fully encoded payment to the first hop in the route
|
// the router to send payment attempts onto the network, and receive
|
||||||
// denoted by its public key. A non-nil error is to be returned if the
|
// their results.
|
||||||
// payment was unsuccessful.
|
Payer PaymentAttemptDispatcher
|
||||||
SendToSwitch func(firstHop lnwire.ShortChannelID,
|
|
||||||
htlcAdd *lnwire.UpdateAddHTLC,
|
|
||||||
circuit *sphinx.Circuit) ([sha256.Size]byte, error)
|
|
||||||
|
|
||||||
// ChannelPruneExpiry is the duration used to determine if a channel
|
// ChannelPruneExpiry is the duration used to determine if a channel
|
||||||
// should be pruned or not. If the delta between now and when the
|
// should be pruned or not. If the delta between now and when the
|
||||||
@ -1698,8 +1707,16 @@ func (r *ChannelRouter) sendToSwitch(route *route.Route, paymentHash [32]byte) (
|
|||||||
firstHop := lnwire.NewShortChanIDFromInt(
|
firstHop := lnwire.NewShortChanIDFromInt(
|
||||||
route.Hops[0].ChannelID,
|
route.Hops[0].ChannelID,
|
||||||
)
|
)
|
||||||
return r.cfg.SendToSwitch(
|
|
||||||
firstHop, htlcAdd, circuit,
|
// Using the created circuit, initialize the error decrypter so we can
|
||||||
|
// parse+decode any failures incurred by this payment within the
|
||||||
|
// switch.
|
||||||
|
errorDecryptor := &htlcswitch.SphinxErrorDecrypter{
|
||||||
|
OnionErrorDecrypter: sphinx.NewOnionErrorDecrypter(circuit),
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.cfg.Payer.SendHTLC(
|
||||||
|
firstHop, htlcAdd, errorDecryptor,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@ import (
|
|||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
|
||||||
sphinx "github.com/lightningnetwork/lightning-onion"
|
|
||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
"github.com/lightningnetwork/lnd/htlcswitch"
|
"github.com/lightningnetwork/lnd/htlcswitch"
|
||||||
"github.com/lightningnetwork/lnd/lntypes"
|
"github.com/lightningnetwork/lnd/lntypes"
|
||||||
@ -44,13 +43,10 @@ func (c *testCtx) RestartRouter() error {
|
|||||||
// With the chainView reset, we'll now re-create the router itself, and
|
// With the chainView reset, we'll now re-create the router itself, and
|
||||||
// start it.
|
// start it.
|
||||||
router, err := New(Config{
|
router, err := New(Config{
|
||||||
Graph: c.graph,
|
Graph: c.graph,
|
||||||
Chain: c.chain,
|
Chain: c.chain,
|
||||||
ChainView: c.chainView,
|
ChainView: c.chainView,
|
||||||
SendToSwitch: func(_ lnwire.ShortChannelID,
|
Payer: &mockPaymentAttemptDispatcher{},
|
||||||
_ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) {
|
|
||||||
return [32]byte{}, nil
|
|
||||||
},
|
|
||||||
ChannelPruneExpiry: time.Hour * 24,
|
ChannelPruneExpiry: time.Hour * 24,
|
||||||
GraphPruneInterval: time.Hour * 2,
|
GraphPruneInterval: time.Hour * 2,
|
||||||
})
|
})
|
||||||
@ -85,14 +81,10 @@ func createTestCtxFromGraphInstance(startingHeight uint32, graphInstance *testGr
|
|||||||
chain := newMockChain(startingHeight)
|
chain := newMockChain(startingHeight)
|
||||||
chainView := newMockChainView(chain)
|
chainView := newMockChainView(chain)
|
||||||
router, err := New(Config{
|
router, err := New(Config{
|
||||||
Graph: graphInstance.graph,
|
Graph: graphInstance.graph,
|
||||||
Chain: chain,
|
Chain: chain,
|
||||||
ChainView: chainView,
|
ChainView: chainView,
|
||||||
SendToSwitch: func(_ lnwire.ShortChannelID,
|
Payer: &mockPaymentAttemptDispatcher{},
|
||||||
_ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) {
|
|
||||||
|
|
||||||
return [32]byte{}, nil
|
|
||||||
},
|
|
||||||
ChannelPruneExpiry: time.Hour * 24,
|
ChannelPruneExpiry: time.Hour * 24,
|
||||||
GraphPruneInterval: time.Hour * 2,
|
GraphPruneInterval: time.Hour * 2,
|
||||||
QueryBandwidth: func(e *channeldb.ChannelEdgeInfo) lnwire.MilliSatoshi {
|
QueryBandwidth: func(e *channeldb.ChannelEdgeInfo) lnwire.MilliSatoshi {
|
||||||
@ -250,24 +242,24 @@ func TestSendPaymentRouteFailureFallback(t *testing.T) {
|
|||||||
// router's configuration to ignore the path that has luo ji as the
|
// router's configuration to ignore the path that has luo ji as the
|
||||||
// first hop. This should force the router to instead take the
|
// first hop. This should force the router to instead take the
|
||||||
// available two hop path (through satoshi).
|
// available two hop path (through satoshi).
|
||||||
ctx.router.cfg.SendToSwitch = func(firstHop lnwire.ShortChannelID,
|
ctx.router.cfg.Payer.(*mockPaymentAttemptDispatcher).setPaymentResult(
|
||||||
_ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) {
|
func(firstHop lnwire.ShortChannelID) ([32]byte, error) {
|
||||||
|
|
||||||
roasbeefLuoji := lnwire.NewShortChanIDFromInt(689530843)
|
roasbeefLuoji := lnwire.NewShortChanIDFromInt(689530843)
|
||||||
if firstHop == roasbeefLuoji {
|
if firstHop == roasbeefLuoji {
|
||||||
pub, err := sourceNode.PubKey()
|
pub, err := sourceNode.PubKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return preImage, err
|
return preImage, err
|
||||||
|
}
|
||||||
|
return [32]byte{}, &htlcswitch.ForwardingError{
|
||||||
|
ErrorSource: pub,
|
||||||
|
// TODO(roasbeef): temp node failure should be?
|
||||||
|
FailureMessage: &lnwire.FailTemporaryChannelFailure{},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return [32]byte{}, &htlcswitch.ForwardingError{
|
|
||||||
ErrorSource: pub,
|
|
||||||
// TODO(roasbeef): temp node failure should be?
|
|
||||||
FailureMessage: &lnwire.FailTemporaryChannelFailure{},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return preImage, nil
|
return preImage, nil
|
||||||
}
|
})
|
||||||
|
|
||||||
// Send off the payment request to the router, route through satoshi
|
// Send off the payment request to the router, route through satoshi
|
||||||
// should've been selected as a fall back and succeeded correctly.
|
// should've been selected as a fall back and succeeded correctly.
|
||||||
@ -387,24 +379,24 @@ func TestChannelUpdateValidation(t *testing.T) {
|
|||||||
// We'll modify the SendToSwitch method so that it simulates a failed
|
// We'll modify the SendToSwitch method so that it simulates a failed
|
||||||
// payment with an error originating from the first hop of the route.
|
// payment with an error originating from the first hop of the route.
|
||||||
// The unsigned channel update is attached to the failure message.
|
// The unsigned channel update is attached to the failure message.
|
||||||
ctx.router.cfg.SendToSwitch = func(firstHop lnwire.ShortChannelID,
|
ctx.router.cfg.Payer.(*mockPaymentAttemptDispatcher).setPaymentResult(
|
||||||
_ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) {
|
func(firstHop lnwire.ShortChannelID) ([32]byte, error) {
|
||||||
|
|
||||||
v := ctx.aliases["b"]
|
v := ctx.aliases["b"]
|
||||||
source, err := btcec.ParsePubKey(
|
source, err := btcec.ParsePubKey(
|
||||||
v[:], btcec.S256(),
|
v[:], btcec.S256(),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return [32]byte{}, &htlcswitch.ForwardingError{
|
return [32]byte{}, &htlcswitch.ForwardingError{
|
||||||
ErrorSource: source,
|
ErrorSource: source,
|
||||||
FailureMessage: &lnwire.FailFeeInsufficient{
|
FailureMessage: &lnwire.FailFeeInsufficient{
|
||||||
Update: errChanUpdate,
|
Update: errChanUpdate,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
|
||||||
// The payment parameter is mostly redundant in SendToRoute. Can be left
|
// The payment parameter is mostly redundant in SendToRoute. Can be left
|
||||||
// empty for this test.
|
// empty for this test.
|
||||||
@ -518,32 +510,32 @@ func TestSendPaymentErrorRepeatedFeeInsufficient(t *testing.T) {
|
|||||||
// We'll now modify the SendToSwitch method to return an error for the
|
// We'll now modify the SendToSwitch method to return an error for the
|
||||||
// outgoing channel to Son goku. This will be a fee related error, so
|
// outgoing channel to Son goku. This will be a fee related error, so
|
||||||
// it should only cause the edge to be pruned after the second attempt.
|
// it should only cause the edge to be pruned after the second attempt.
|
||||||
ctx.router.cfg.SendToSwitch = func(firstHop lnwire.ShortChannelID,
|
ctx.router.cfg.Payer.(*mockPaymentAttemptDispatcher).setPaymentResult(
|
||||||
_ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) {
|
func(firstHop lnwire.ShortChannelID) ([32]byte, error) {
|
||||||
|
|
||||||
roasbeefSongoku := lnwire.NewShortChanIDFromInt(chanID)
|
roasbeefSongoku := lnwire.NewShortChanIDFromInt(chanID)
|
||||||
if firstHop == roasbeefSongoku {
|
if firstHop == roasbeefSongoku {
|
||||||
sourceKey, err := btcec.ParsePubKey(
|
sourceKey, err := btcec.ParsePubKey(
|
||||||
sourceNode[:], btcec.S256(),
|
sourceNode[:], btcec.S256(),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return [32]byte{}, &htlcswitch.ForwardingError{
|
||||||
|
ErrorSource: sourceKey,
|
||||||
|
|
||||||
|
// Within our error, we'll add a channel update
|
||||||
|
// which is meant to reflect he new fee
|
||||||
|
// schedule for the node/channel.
|
||||||
|
FailureMessage: &lnwire.FailFeeInsufficient{
|
||||||
|
Update: errChanUpdate,
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return [32]byte{}, &htlcswitch.ForwardingError{
|
return preImage, nil
|
||||||
ErrorSource: sourceKey,
|
})
|
||||||
|
|
||||||
// Within our error, we'll add a channel update
|
|
||||||
// which is meant to reflect he new fee
|
|
||||||
// schedule for the node/channel.
|
|
||||||
FailureMessage: &lnwire.FailFeeInsufficient{
|
|
||||||
Update: errChanUpdate,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return preImage, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send off the payment request to the router, route through satoshi
|
// Send off the payment request to the router, route through satoshi
|
||||||
// should've been selected as a fall back and succeeded correctly.
|
// should've been selected as a fall back and succeeded correctly.
|
||||||
@ -633,27 +625,27 @@ func TestSendPaymentErrorNonFinalTimeLockErrors(t *testing.T) {
|
|||||||
// outgoing channel to son goku. Since this is a time lock related
|
// outgoing channel to son goku. Since this is a time lock related
|
||||||
// error, we should fail the payment flow all together, as Goku is the
|
// error, we should fail the payment flow all together, as Goku is the
|
||||||
// only channel to Sophon.
|
// only channel to Sophon.
|
||||||
ctx.router.cfg.SendToSwitch = func(firstHop lnwire.ShortChannelID,
|
ctx.router.cfg.Payer.(*mockPaymentAttemptDispatcher).setPaymentResult(
|
||||||
_ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) {
|
func(firstHop lnwire.ShortChannelID) ([32]byte, error) {
|
||||||
|
|
||||||
if firstHop == roasbeefSongoku {
|
if firstHop == roasbeefSongoku {
|
||||||
sourceKey, err := btcec.ParsePubKey(
|
sourceKey, err := btcec.ParsePubKey(
|
||||||
sourceNode[:], btcec.S256(),
|
sourceNode[:], btcec.S256(),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return [32]byte{}, &htlcswitch.ForwardingError{
|
||||||
|
ErrorSource: sourceKey,
|
||||||
|
FailureMessage: &lnwire.FailExpiryTooSoon{
|
||||||
|
Update: errChanUpdate,
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return [32]byte{}, &htlcswitch.ForwardingError{
|
return preImage, nil
|
||||||
ErrorSource: sourceKey,
|
})
|
||||||
FailureMessage: &lnwire.FailExpiryTooSoon{
|
|
||||||
Update: errChanUpdate,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return preImage, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// assertExpectedPath is a helper function that asserts the returned
|
// assertExpectedPath is a helper function that asserts the returned
|
||||||
// route properly routes around the failure we've introduced in the
|
// route properly routes around the failure we've introduced in the
|
||||||
@ -694,27 +686,27 @@ func TestSendPaymentErrorNonFinalTimeLockErrors(t *testing.T) {
|
|||||||
// We'll now modify the error return an IncorrectCltvExpiry error
|
// We'll now modify the error return an IncorrectCltvExpiry error
|
||||||
// instead, this should result in the same behavior of roasbeef routing
|
// instead, this should result in the same behavior of roasbeef routing
|
||||||
// around the faulty Son Goku node.
|
// around the faulty Son Goku node.
|
||||||
ctx.router.cfg.SendToSwitch = func(firstHop lnwire.ShortChannelID,
|
ctx.router.cfg.Payer.(*mockPaymentAttemptDispatcher).setPaymentResult(
|
||||||
_ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) {
|
func(firstHop lnwire.ShortChannelID) ([32]byte, error) {
|
||||||
|
|
||||||
if firstHop == roasbeefSongoku {
|
if firstHop == roasbeefSongoku {
|
||||||
sourceKey, err := btcec.ParsePubKey(
|
sourceKey, err := btcec.ParsePubKey(
|
||||||
sourceNode[:], btcec.S256(),
|
sourceNode[:], btcec.S256(),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return [32]byte{}, &htlcswitch.ForwardingError{
|
||||||
|
ErrorSource: sourceKey,
|
||||||
|
FailureMessage: &lnwire.FailIncorrectCltvExpiry{
|
||||||
|
Update: errChanUpdate,
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return [32]byte{}, &htlcswitch.ForwardingError{
|
return preImage, nil
|
||||||
ErrorSource: sourceKey,
|
})
|
||||||
FailureMessage: &lnwire.FailIncorrectCltvExpiry{
|
|
||||||
Update: errChanUpdate,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return preImage, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Once again, Roasbeef should route around Goku since they disagree
|
// Once again, Roasbeef should route around Goku since they disagree
|
||||||
// w.r.t to the block height, and instead go through Pham Nuwen.
|
// w.r.t to the block height, and instead go through Pham Nuwen.
|
||||||
@ -771,40 +763,40 @@ func TestSendPaymentErrorPathPruning(t *testing.T) {
|
|||||||
//
|
//
|
||||||
// TODO(roasbeef): filtering should be intelligent enough so just not
|
// TODO(roasbeef): filtering should be intelligent enough so just not
|
||||||
// go through satoshi at all at this point.
|
// go through satoshi at all at this point.
|
||||||
ctx.router.cfg.SendToSwitch = func(firstHop lnwire.ShortChannelID,
|
ctx.router.cfg.Payer.(*mockPaymentAttemptDispatcher).setPaymentResult(
|
||||||
_ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) {
|
func(firstHop lnwire.ShortChannelID) ([32]byte, error) {
|
||||||
|
|
||||||
if firstHop == roasbeefLuoji {
|
if firstHop == roasbeefLuoji {
|
||||||
// We'll first simulate an error from the first
|
// We'll first simulate an error from the first
|
||||||
// outgoing link to simulate the channel from luo ji to
|
// outgoing link to simulate the channel from luo ji to
|
||||||
// roasbeef not having enough capacity.
|
// roasbeef not having enough capacity.
|
||||||
return [32]byte{}, &htlcswitch.ForwardingError{
|
return [32]byte{}, &htlcswitch.ForwardingError{
|
||||||
ErrorSource: sourcePub,
|
ErrorSource: sourcePub,
|
||||||
FailureMessage: &lnwire.FailTemporaryChannelFailure{},
|
FailureMessage: &lnwire.FailTemporaryChannelFailure{},
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Next, we'll create an error from satoshi to indicate
|
|
||||||
// that the luoji node is not longer online, which should
|
|
||||||
// prune out the rest of the routes.
|
|
||||||
roasbeefSatoshi := lnwire.NewShortChanIDFromInt(2340213491)
|
|
||||||
if firstHop == roasbeefSatoshi {
|
|
||||||
vertex := ctx.aliases["satoshi"]
|
|
||||||
key, err := btcec.ParsePubKey(
|
|
||||||
vertex[:], btcec.S256(),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return [32]byte{}, &htlcswitch.ForwardingError{
|
// Next, we'll create an error from satoshi to indicate
|
||||||
ErrorSource: key,
|
// that the luoji node is not longer online, which should
|
||||||
FailureMessage: &lnwire.FailUnknownNextPeer{},
|
// prune out the rest of the routes.
|
||||||
}
|
roasbeefSatoshi := lnwire.NewShortChanIDFromInt(2340213491)
|
||||||
}
|
if firstHop == roasbeefSatoshi {
|
||||||
|
vertex := ctx.aliases["satoshi"]
|
||||||
|
key, err := btcec.ParsePubKey(
|
||||||
|
vertex[:], btcec.S256(),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
return preImage, nil
|
return [32]byte{}, &htlcswitch.ForwardingError{
|
||||||
}
|
ErrorSource: key,
|
||||||
|
FailureMessage: &lnwire.FailUnknownNextPeer{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return preImage, nil
|
||||||
|
})
|
||||||
|
|
||||||
ctx.router.missionControl.ResetHistory()
|
ctx.router.missionControl.ResetHistory()
|
||||||
|
|
||||||
@ -826,18 +818,18 @@ func TestSendPaymentErrorPathPruning(t *testing.T) {
|
|||||||
// Next, we'll modify the SendToSwitch method to indicate that luo ji
|
// Next, we'll modify the SendToSwitch method to indicate that luo ji
|
||||||
// wasn't originally online. This should also halt the send all
|
// wasn't originally online. This should also halt the send all
|
||||||
// together as all paths contain luoji and he can't be reached.
|
// together as all paths contain luoji and he can't be reached.
|
||||||
ctx.router.cfg.SendToSwitch = func(firstHop lnwire.ShortChannelID,
|
ctx.router.cfg.Payer.(*mockPaymentAttemptDispatcher).setPaymentResult(
|
||||||
_ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) {
|
func(firstHop lnwire.ShortChannelID) ([32]byte, error) {
|
||||||
|
|
||||||
if firstHop == roasbeefLuoji {
|
if firstHop == roasbeefLuoji {
|
||||||
return [32]byte{}, &htlcswitch.ForwardingError{
|
return [32]byte{}, &htlcswitch.ForwardingError{
|
||||||
ErrorSource: sourcePub,
|
ErrorSource: sourcePub,
|
||||||
FailureMessage: &lnwire.FailUnknownNextPeer{},
|
FailureMessage: &lnwire.FailUnknownNextPeer{},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return preImage, nil
|
return preImage, nil
|
||||||
}
|
})
|
||||||
|
|
||||||
// This shouldn't return an error, as we'll make a payment attempt via
|
// This shouldn't return an error, as we'll make a payment attempt via
|
||||||
// the satoshi channel based on the assumption that there might be an
|
// the satoshi channel based on the assumption that there might be an
|
||||||
@ -869,20 +861,20 @@ func TestSendPaymentErrorPathPruning(t *testing.T) {
|
|||||||
// Finally, we'll modify the SendToSwitch function to indicate that the
|
// Finally, we'll modify the SendToSwitch function to indicate that the
|
||||||
// roasbeef -> luoji channel has insufficient capacity. This should
|
// roasbeef -> luoji channel has insufficient capacity. This should
|
||||||
// again cause us to instead go via the satoshi route.
|
// again cause us to instead go via the satoshi route.
|
||||||
ctx.router.cfg.SendToSwitch = func(firstHop lnwire.ShortChannelID,
|
ctx.router.cfg.Payer.(*mockPaymentAttemptDispatcher).setPaymentResult(
|
||||||
_ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) {
|
func(firstHop lnwire.ShortChannelID) ([32]byte, error) {
|
||||||
|
|
||||||
if firstHop == roasbeefLuoji {
|
if firstHop == roasbeefLuoji {
|
||||||
// We'll first simulate an error from the first
|
// We'll first simulate an error from the first
|
||||||
// outgoing link to simulate the channel from luo ji to
|
// outgoing link to simulate the channel from luo ji to
|
||||||
// roasbeef not having enough capacity.
|
// roasbeef not having enough capacity.
|
||||||
return [32]byte{}, &htlcswitch.ForwardingError{
|
return [32]byte{}, &htlcswitch.ForwardingError{
|
||||||
ErrorSource: sourcePub,
|
ErrorSource: sourcePub,
|
||||||
FailureMessage: &lnwire.FailTemporaryChannelFailure{},
|
FailureMessage: &lnwire.FailTemporaryChannelFailure{},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return preImage, nil
|
||||||
return preImage, nil
|
})
|
||||||
}
|
|
||||||
|
|
||||||
paymentPreImage, rt, err = ctx.router.SendPayment(&payment)
|
paymentPreImage, rt, err = ctx.router.SendPayment(&payment)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1525,13 +1517,10 @@ func TestWakeUpOnStaleBranch(t *testing.T) {
|
|||||||
|
|
||||||
// Create new router with same graph database.
|
// Create new router with same graph database.
|
||||||
router, err := New(Config{
|
router, err := New(Config{
|
||||||
Graph: ctx.graph,
|
Graph: ctx.graph,
|
||||||
Chain: ctx.chain,
|
Chain: ctx.chain,
|
||||||
ChainView: ctx.chainView,
|
ChainView: ctx.chainView,
|
||||||
SendToSwitch: func(_ lnwire.ShortChannelID,
|
Payer: &mockPaymentAttemptDispatcher{},
|
||||||
_ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) {
|
|
||||||
return [32]byte{}, nil
|
|
||||||
},
|
|
||||||
ChannelPruneExpiry: time.Hour * 24,
|
ChannelPruneExpiry: time.Hour * 24,
|
||||||
GraphPruneInterval: time.Hour * 2,
|
GraphPruneInterval: time.Hour * 2,
|
||||||
})
|
})
|
||||||
|
22
server.go
22
server.go
@ -610,24 +610,10 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB, cc *chainControl,
|
|||||||
s.currentNodeAnn = nodeAnn
|
s.currentNodeAnn = nodeAnn
|
||||||
|
|
||||||
s.chanRouter, err = routing.New(routing.Config{
|
s.chanRouter, err = routing.New(routing.Config{
|
||||||
Graph: chanGraph,
|
Graph: chanGraph,
|
||||||
Chain: cc.chainIO,
|
Chain: cc.chainIO,
|
||||||
ChainView: cc.chainView,
|
ChainView: cc.chainView,
|
||||||
SendToSwitch: func(firstHop lnwire.ShortChannelID,
|
Payer: s.htlcSwitch,
|
||||||
htlcAdd *lnwire.UpdateAddHTLC,
|
|
||||||
circuit *sphinx.Circuit) ([32]byte, error) {
|
|
||||||
|
|
||||||
// Using the created circuit, initialize the error
|
|
||||||
// decrypter so we can parse+decode any failures
|
|
||||||
// incurred by this payment within the switch.
|
|
||||||
errorDecryptor := &htlcswitch.SphinxErrorDecrypter{
|
|
||||||
OnionErrorDecrypter: sphinx.NewOnionErrorDecrypter(circuit),
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.htlcSwitch.SendHTLC(
|
|
||||||
firstHop, htlcAdd, errorDecryptor,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
ChannelPruneExpiry: routing.DefaultChannelPruneExpiry,
|
ChannelPruneExpiry: routing.DefaultChannelPruneExpiry,
|
||||||
GraphPruneInterval: time.Duration(time.Hour),
|
GraphPruneInterval: time.Duration(time.Hour),
|
||||||
QueryBandwidth: func(edge *channeldb.ChannelEdgeInfo) lnwire.MilliSatoshi {
|
QueryBandwidth: func(edge *channeldb.ChannelEdgeInfo) lnwire.MilliSatoshi {
|
||||||
|
Loading…
Reference in New Issue
Block a user