mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 01:43:16 +01:00
routing+docs: make sure non-MPP cannot use skipTempErr
This commit is contained in:
parent
168cfd7cd5
commit
678f416008
@ -91,6 +91,12 @@
|
||||
hash](https://github.com/lightningnetwork/lnd/pull/8106) to the
|
||||
signer.SignMessage/signer.VerifyMessage RPCs.
|
||||
|
||||
* `sendtoroute` will return an error when it's called using the flag
|
||||
`--skip_temp_err` on a payment that's not a MPP. This is needed as a temp
|
||||
error is defined as a routing error found in one of a MPP's HTLC attempts.
|
||||
If, however, there's only one HTLC attempt, when it's failed, this payment is
|
||||
considered failed, thus there's no such thing as temp error for a non-MPP.
|
||||
|
||||
## lncli Updates
|
||||
## Code Health
|
||||
|
||||
|
@ -119,6 +119,10 @@ var (
|
||||
// provided by either a blinded route or a cleartext pubkey.
|
||||
ErrNoTarget = errors.New("destination not set in target or blinded " +
|
||||
"path")
|
||||
|
||||
// ErrSkipTempErr is returned when a non-MPP is made yet the
|
||||
// skipTempErr flag is set.
|
||||
ErrSkipTempErr = errors.New("cannot skip temp error for non-MPP")
|
||||
)
|
||||
|
||||
// ChannelGraphSource represents the source of information about the topology
|
||||
@ -2450,6 +2454,13 @@ func (r *ChannelRouter) sendToRoute(htlcHash lntypes.Hash, rt *route.Route,
|
||||
amt = mpp.TotalMsat()
|
||||
}
|
||||
|
||||
// For non-MPP, there's no such thing as temp error as there's only one
|
||||
// HTLC attempt being made. When this HTLC is failed, the payment is
|
||||
// failed hence cannot be retried.
|
||||
if skipTempErr && mpp == nil {
|
||||
return nil, ErrSkipTempErr
|
||||
}
|
||||
|
||||
// For non-AMP payments the overall payment identifier will be the same
|
||||
// hash as used for this HTLC.
|
||||
paymentIdentifier := htlcHash
|
||||
|
@ -3384,7 +3384,8 @@ func TestBlockDifferenceFix(t *testing.T) {
|
||||
|
||||
initialBlockHeight := uint32(0)
|
||||
|
||||
// Starting height here is set to 0, which is behind where we want to be.
|
||||
// Starting height here is set to 0, which is behind where we want to
|
||||
// be.
|
||||
ctx := createTestCtxSingleNode(t, initialBlockHeight)
|
||||
|
||||
// Add initial block to our mini blockchain.
|
||||
@ -3454,6 +3455,8 @@ func TestBlockDifferenceFix(t *testing.T) {
|
||||
|
||||
// TestSendToRouteSkipTempErrSuccess validates a successful payment send.
|
||||
func TestSendToRouteSkipTempErrSuccess(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
payHash lntypes.Hash
|
||||
payAmt = lnwire.MilliSatoshi(10000)
|
||||
@ -3536,9 +3539,62 @@ func TestSendToRouteSkipTempErrSuccess(t *testing.T) {
|
||||
payment.AssertExpectations(t)
|
||||
}
|
||||
|
||||
// TestSendToRouteSkipTempErrNonMPP checks that an error is return when
|
||||
// skipping temp error for non-MPP.
|
||||
func TestSendToRouteSkipTempErrNonMPP(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
payHash lntypes.Hash
|
||||
payAmt = lnwire.MilliSatoshi(10000)
|
||||
)
|
||||
|
||||
node, err := createTestNode()
|
||||
require.NoError(t, err)
|
||||
|
||||
// Create a simple 1-hop route without the MPP field.
|
||||
hops := []*route.Hop{
|
||||
{
|
||||
ChannelID: 1,
|
||||
PubKeyBytes: node.PubKeyBytes,
|
||||
AmtToForward: payAmt,
|
||||
},
|
||||
}
|
||||
rt, err := route.NewRouteFromHops(payAmt, 100, node.PubKeyBytes, hops)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Create mockers.
|
||||
controlTower := &mockControlTower{}
|
||||
payer := &mockPaymentAttemptDispatcher{}
|
||||
missionControl := &mockMissionControl{}
|
||||
|
||||
// Create the router.
|
||||
router := &ChannelRouter{cfg: &Config{
|
||||
Control: controlTower,
|
||||
Payer: payer,
|
||||
MissionControl: missionControl,
|
||||
Clock: clock.NewTestClock(time.Unix(1, 0)),
|
||||
NextPaymentID: func() (uint64, error) {
|
||||
return 0, nil
|
||||
},
|
||||
}}
|
||||
|
||||
// Expect an error to be returned.
|
||||
attempt, err := router.SendToRouteSkipTempErr(payHash, rt)
|
||||
require.ErrorIs(t, ErrSkipTempErr, err)
|
||||
require.Nil(t, attempt)
|
||||
|
||||
// Assert the above methods are not called.
|
||||
controlTower.AssertExpectations(t)
|
||||
payer.AssertExpectations(t)
|
||||
missionControl.AssertExpectations(t)
|
||||
}
|
||||
|
||||
// TestSendToRouteSkipTempErrTempFailure validates a temporary failure won't
|
||||
// cause the payment to be failed.
|
||||
func TestSendToRouteSkipTempErrTempFailure(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
payHash lntypes.Hash
|
||||
payAmt = lnwire.MilliSatoshi(10000)
|
||||
|
Loading…
Reference in New Issue
Block a user