Merge pull request #1655 from Roasbeef/send-to-route-defense

routing: ensure generateSphinxPacket can handle being passed empty set of routes
This commit is contained in:
Olaoluwa Osuntokun 2018-07-30 18:56:57 -04:00 committed by GitHub
commit 2e6e2a06c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 2 deletions

@ -38,6 +38,13 @@ const (
defaultPayAttemptTimeout = time.Duration(time.Second * 60) defaultPayAttemptTimeout = time.Duration(time.Second * 60)
) )
var (
// ErrNoRouteHopsProvided is returned when a caller attempts to
// construct a new sphinx packet, but provides an empty set of hops for
// each route.
ErrNoRouteHopsProvided = fmt.Errorf("empty route hops provided")
)
// ChannelGraphSource represents the source of information about the topology // ChannelGraphSource represents the source of information about the topology
// of the lightning network. It's responsible for the addition of nodes, edges, // of the lightning network. It's responsible for the addition of nodes, edges,
// applying edge updates, and returning the current block height with which the // applying edge updates, and returning the current block height with which the
@ -1412,6 +1419,14 @@ func (r *ChannelRouter) FindRoutes(target *btcec.PublicKey,
// be sent to the first hop within the route. // be sent to the first hop within the route.
func generateSphinxPacket(route *Route, paymentHash []byte) ([]byte, func generateSphinxPacket(route *Route, paymentHash []byte) ([]byte,
*sphinx.Circuit, error) { *sphinx.Circuit, error) {
// As a sanity check, we'll ensure that the set of hops has been
// properly filled in, otherwise, we won't actually be able to
// construct a route.
if len(route.Hops) == 0 {
return nil, nil, ErrNoRouteHopsProvided
}
// First obtain all the public keys along the route which are contained // First obtain all the public keys along the route which are contained
// in each hop. // in each hop.
nodes := make([]*btcec.PublicKey, len(route.Hops)) nodes := make([]*btcec.PublicKey, len(route.Hops))

@ -9,14 +9,14 @@ import (
"testing" "testing"
"time" "time"
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/htlcswitch" "github.com/lightningnetwork/lnd/htlcswitch"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcd/btcec"
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
"github.com/lightningnetwork/lightning-onion" "github.com/lightningnetwork/lightning-onion"
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
"github.com/btcsuite/btcd/btcec"
) )
// defaultNumRoutes is the default value for the maximum number of routes to // defaultNumRoutes is the default value for the maximum number of routes to
@ -1941,3 +1941,16 @@ func TestIsStaleEdgePolicy(t *testing.T) {
t.Fatalf("router failed to detect fresh edge policy") t.Fatalf("router failed to detect fresh edge policy")
} }
} }
// TestEmptyRoutesGenerateSphinxPacket tests that the generateSphinxPacket
// function is able to gracefully handle being passed a nil set of hops for the
// route by the caller.
func TestEmptyRoutesGenerateSphinxPacket(t *testing.T) {
t.Parallel()
emptyRoute := &Route{}
_, _, err := generateSphinxPacket(emptyRoute, testHash[:])
if err != ErrNoRouteHopsProvided {
t.Fatalf("expected empty hops error: instead got: %v", err)
}
}