Skip to content

Commit c01a667

Browse files
committed
routerrpc: inject clock for testable expiry validation
Refactors payment request expiry validation to use an injected clock dependency instead of calling time.Now() directly.
1 parent a27bd69 commit c01a667

File tree

3 files changed

+18
-4
lines changed

3 files changed

+18
-4
lines changed

lnrpc/routerrpc/router_backend.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/btcsuite/btcd/wire"
1616
sphinx "github.com/lightningnetwork/lightning-onion"
1717
"github.com/lightningnetwork/lnd/channeldb"
18+
"github.com/lightningnetwork/lnd/clock"
1819
"github.com/lightningnetwork/lnd/feature"
1920
"github.com/lightningnetwork/lnd/fn/v2"
2021
"github.com/lightningnetwork/lnd/htlcswitch"
@@ -118,6 +119,10 @@ type RouterBackend struct {
118119
// ShouldSetExpEndorsement returns a boolean indicating whether the
119120
// experimental endorsement bit should be set.
120121
ShouldSetExpEndorsement func() bool
122+
123+
// Clock is the clock used to validate payment requests expiry.
124+
// It is useful for testing.
125+
Clock clock.Clock
121126
}
122127

123128
// MissionControl defines the mission control dependencies of routerrpc.
@@ -980,7 +985,7 @@ func (r *RouterBackend) extractIntentFromSendRequest(
980985
}
981986

982987
// Next, we'll ensure that this payreq hasn't already expired.
983-
err = ValidatePayReqExpiry(payReq)
988+
err = ValidatePayReqExpiry(r.Clock, payReq)
984989
if err != nil {
985990
return nil, err
986991
}
@@ -1370,10 +1375,10 @@ func UnmarshalFeatures(
13701375

13711376
// ValidatePayReqExpiry checks if the passed payment request has expired. In
13721377
// the case it has expired, an error will be returned.
1373-
func ValidatePayReqExpiry(payReq *zpay32.Invoice) error {
1378+
func ValidatePayReqExpiry(clock clock.Clock, payReq *zpay32.Invoice) error {
13741379
expiry := payReq.Expiry()
13751380
validUntil := payReq.Timestamp.Add(expiry)
1376-
if time.Now().After(validUntil) {
1381+
if clock.Now().After(validUntil) {
13771382
return fmt.Errorf("invoice expired. Valid until %v", validUntil)
13781383
}
13791384

lnrpc/routerrpc/router_backend_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ import (
55
"context"
66
"encoding/hex"
77
"testing"
8+
"time"
89

910
"github.com/btcsuite/btcd/btcutil"
1011
"github.com/btcsuite/btcd/chaincfg"
12+
"github.com/lightningnetwork/lnd/lnmock"
1113
"github.com/lightningnetwork/lnd/lnrpc"
1214
"github.com/lightningnetwork/lnd/lnwire"
1315
"github.com/lightningnetwork/lnd/record"
@@ -509,6 +511,9 @@ func TestExtractIntentFromSendRequest(t *testing.T) {
509511
target, err := route.NewVertexFromBytes(destNodeBytes)
510512
require.NoError(t, err)
511513

514+
mockClock := &lnmock.MockClock{}
515+
mockClock.On("Now").Return(time.Date(2025, 3, 1, 13, 0, 0, 0, time.UTC))
516+
512517
testCases := []extractIntentTestCase{
513518
{
514519
name: "Time preference out of range",
@@ -706,6 +711,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) {
706711
return false
707712
},
708713
ActiveNetParams: &chaincfg.RegressionNetParams,
714+
Clock: mockClock,
709715
},
710716
sendReq: &SendPaymentRequest{
711717
Amt: int64(paymentAmount),

rpcserver.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,7 @@ func (r *rpcServer) addDeps(s *server, macService *macaroons.Service,
696696

697697
routerBackend := &routerrpc.RouterBackend{
698698
SelfNode: selfNode.PubKeyBytes,
699+
Clock: clock.NewDefaultClock(),
699700
FetchChannelCapacity: func(chanID uint64) (btcutil.Amount,
700701
error) {
701702

@@ -5609,7 +5610,9 @@ func (r *rpcServer) extractPaymentIntent(rpcPayReq *rpcPaymentRequest) (rpcPayme
56095610
}
56105611

56115612
// Next, we'll ensure that this payreq hasn't already expired.
5612-
err = routerrpc.ValidatePayReqExpiry(payReq)
5613+
err = routerrpc.ValidatePayReqExpiry(
5614+
r.routerBackend.Clock, payReq,
5615+
)
56135616
if err != nil {
56145617
return payIntent, err
56155618
}

0 commit comments

Comments
 (0)