diff --git a/routing/notifications.go b/routing/notifications.go index e4d1f6486..dab7e5d23 100644 --- a/routing/notifications.go +++ b/routing/notifications.go @@ -9,6 +9,7 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/go-errors/errors" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/lnwire" "github.com/roasbeef/btcd/btcec" "github.com/roasbeef/btcd/wire" "github.com/roasbeef/btcutil" @@ -254,15 +255,15 @@ type ChannelEdgeUpdate struct { Capacity btcutil.Amount // MinHTLC is the minimum HTLC amount that this channel will forward. - MinHTLC btcutil.Amount + MinHTLC lnwire.MilliSatoshi // BaseFee is the base fee that will charged for all HTLC's forwarded // across the this channel direction. - BaseFee btcutil.Amount + BaseFee lnwire.MilliSatoshi // FeeRate is the fee rate that will be shared for all HTLC's forwarded // across this channel direction. - FeeRate btcutil.Amount + FeeRate lnwire.MilliSatoshi // TimeLockDelta is the time-lock expressed in blocks that will be // added to outgoing HTLC's from incoming HTLC's. This value is the diff --git a/routing/notifications_test.go b/routing/notifications_test.go index 73f52088f..73ff25d05 100644 --- a/routing/notifications_test.go +++ b/routing/notifications_test.go @@ -71,22 +71,22 @@ func randEdgePolicy(chanID *lnwire.ShortChannelID, ChannelID: chanID.ToUint64(), LastUpdate: time.Unix(int64(prand.Int31()), 0), TimeLockDelta: uint16(prand.Int63()), - MinHTLC: btcutil.Amount(prand.Int31()), - FeeBaseMSat: btcutil.Amount(prand.Int31()), - FeeProportionalMillionths: btcutil.Amount(prand.Int31()), + MinHTLC: lnwire.MilliSatoshi(prand.Int31()), + FeeBaseMSat: lnwire.MilliSatoshi(prand.Int31()), + FeeProportionalMillionths: lnwire.MilliSatoshi(prand.Int31()), Node: node, } } func createChannelEdge(ctx *testCtx, bitcoinKey1, bitcoinKey2 []byte, - chanValue int64, fundingHeight uint32) (*wire.MsgTx, *wire.OutPoint, + chanValue btcutil.Amount, fundingHeight uint32) (*wire.MsgTx, *wire.OutPoint, *lnwire.ShortChannelID, error) { fundingTx := wire.NewMsgTx(2) _, tx, err := lnwallet.GenFundingPkScript( bitcoinKey1, bitcoinKey2, - chanValue, + int64(chanValue), ) if err != nil { return nil, nil, nil, err @@ -365,17 +365,17 @@ func TestEdgeUpdateNotification(t *testing.T) { t.Fatalf("capacity of edge doesn't match: "+ "expected %v, got %v", chanValue, edgeUpdate.Capacity) } - if edgeUpdate.MinHTLC != btcutil.Amount(edgeAnn.MinHTLC) { + if edgeUpdate.MinHTLC != edgeAnn.MinHTLC { t.Fatalf("min HTLC of edge doesn't match: "+ - "expected %v, got %v", btcutil.Amount(edgeAnn.MinHTLC), + "expected %v, got %v", edgeAnn.MinHTLC, edgeUpdate.MinHTLC) } - if edgeUpdate.BaseFee != btcutil.Amount(edgeAnn.FeeBaseMSat) { + if edgeUpdate.BaseFee != edgeAnn.FeeBaseMSat { t.Fatalf("base fee of edge doesn't match: "+ "expected %v, got %v", edgeAnn.FeeBaseMSat, edgeUpdate.BaseFee) } - if edgeUpdate.FeeRate != btcutil.Amount(edgeAnn.FeeProportionalMillionths) { + if edgeUpdate.FeeRate != edgeAnn.FeeProportionalMillionths { t.Fatalf("fee rate of edge doesn't match: "+ "expected %v, got %v", edgeAnn.FeeProportionalMillionths, edgeUpdate.FeeRate) diff --git a/routing/pathfind.go b/routing/pathfind.go index e41ff1f0a..77a0434b9 100644 --- a/routing/pathfind.go +++ b/routing/pathfind.go @@ -2,6 +2,7 @@ package routing import ( "encoding/binary" + "fmt" "math" "container/heap" @@ -9,6 +10,7 @@ import ( "github.com/boltdb/bolt" "github.com/lightningnetwork/lightning-onion" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/lnwire" "github.com/roasbeef/btcd/btcec" "github.com/roasbeef/btcd/chaincfg/chainhash" "github.com/roasbeef/btcutil" @@ -60,18 +62,18 @@ type Hop struct { // AmtToForward is the amount that this hop will forward to the next // hop. This value is less than the value that the incoming HTLC // carries as a fee will be subtracted by the hop. - AmtToForward btcutil.Amount + AmtToForward lnwire.MilliSatoshi // Fee is the total fee that this hop will subtract from the incoming // payment, this difference nets the hop fees for forwarding the // payment. - Fee btcutil.Amount + Fee lnwire.MilliSatoshi } -// computeFee computes the fee to forward an HTLC of `amt` satoshis over the -// passed active payment channel. This value is currently computed as specified -// in BOLT07, but will likely change in the near future. -func computeFee(amt btcutil.Amount, edge *ChannelHop) btcutil.Amount { +// computeFee computes the fee to forward an HTLC of `amt` milli-satoshis over +// the passed active payment channel. This value is currently computed as +// specified in BOLT07, but will likely change in the near future. +func computeFee(amt lnwire.MilliSatoshi, edge *ChannelHop) lnwire.MilliSatoshi { return edge.FeeBaseMSat + (amt*edge.FeeProportionalMillionths)/1000000 } @@ -108,7 +110,7 @@ type Route struct { // TotalFees is the sum of the fees paid at each hop within the final // route. In the case of a one-hop payment, this value will be zero as // we don't need to pay a fee it ourself. - TotalFees btcutil.Amount + TotalFees lnwire.MilliSatoshi // TotalAmount is the total amount of funds required to complete a // payment over this route. This value includes the cumulative fees at @@ -116,7 +118,7 @@ type Route struct { // route will need to have at least this many satoshis, otherwise the // route will fail at an intermediate node due to an insufficient // amount of fees. - TotalAmount btcutil.Amount + TotalAmount lnwire.MilliSatoshi // Hops contains details concerning the specific forwarding details at // each hop. @@ -199,7 +201,7 @@ func (s sortableRoutes) Swap(i, j int) { // // NOTE: The passed slice of ChannelHops MUST be sorted in forward order: from // the source to the target node of the path finding attempt. -func newRoute(amtToSend btcutil.Amount, pathEdges []*ChannelHop, +func newRoute(amtToSend lnwire.MilliSatoshi, pathEdges []*ChannelHop, currentHeight uint32) (*Route, error) { // First, we'll create a new empty route with enough hops to match the @@ -236,9 +238,13 @@ func newRoute(amtToSend btcutil.Amount, pathEdges []*ChannelHop, // As a sanity check, we ensure that the selected channel has // enough capacity to forward the required amount which // includes the fee dictated at each hop. - if nextHop.AmtToForward > nextHop.Channel.Capacity { - return nil, newErrf(ErrInsufficientCapacity, "channel graph has "+ - "insufficient capacity for the payment") + if nextHop.AmtToForward.ToSatoshis() > nextHop.Channel.Capacity { + err := fmt.Sprintf("channel graph has insufficient "+ + "capacity for the payment: need %v, have %v", + nextHop.AmtToForward.ToSatoshis(), + nextHop.Channel.Capacity) + + return nil, newErrf(ErrInsufficientCapacity, err) } // We don't pay any fees to ourselves on the first-hop channel, @@ -329,7 +335,7 @@ func edgeWeight(e *channeldb.ChannelEdgePolicy) float64 { // from the target to the source. func findPath(graph *channeldb.ChannelGraph, sourceNode *channeldb.LightningNode, target *btcec.PublicKey, ignoredNodes map[vertex]struct{}, - ignoredEdges map[uint64]struct{}, amt btcutil.Amount) ([]*ChannelHop, error) { + ignoredEdges map[uint64]struct{}, amt lnwire.MilliSatoshi) ([]*ChannelHop, error) { // First we'll initialize an empty heap which'll help us to quickly // locate the next edge we should visit next during our graph @@ -414,7 +420,7 @@ func findPath(graph *channeldb.ChannelGraph, sourceNode *channeldb.LightningNode // off irrelevant edges by adding the sufficient // capacity of an edge to our relaxation condition. if tempDist < distance[v].dist && - edgeInfo.Capacity >= amt { + edgeInfo.Capacity >= amt.ToSatoshis() { // TODO(roasbeef): need to also account // for min HTLC @@ -497,7 +503,7 @@ func findPath(graph *channeldb.ChannelGraph, sourceNode *channeldb.LightningNode // algorithm, rather than attempting to use an unmodified path finding // algorithm in a block box manner. func findPaths(graph *channeldb.ChannelGraph, source *channeldb.LightningNode, - target *btcec.PublicKey, amt btcutil.Amount) ([][]*ChannelHop, error) { + target *btcec.PublicKey, amt lnwire.MilliSatoshi) ([][]*ChannelHop, error) { ignoredEdges := make(map[uint64]struct{}) ignoredVertexes := make(map[vertex]struct{}) diff --git a/routing/pathfind_test.go b/routing/pathfind_test.go index 01c27bf5f..5b26813bf 100644 --- a/routing/pathfind_test.go +++ b/routing/pathfind_test.go @@ -15,6 +15,7 @@ import ( "time" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/lnwire" "github.com/roasbeef/btcd/btcec" "github.com/roasbeef/btcd/chaincfg/chainhash" "github.com/roasbeef/btcd/wire" @@ -265,9 +266,9 @@ func parseTestGraph(path string) (*channeldb.ChannelGraph, func(), aliasMap, err ChannelID: edge.ChannelID, LastUpdate: time.Now(), TimeLockDelta: edge.Expiry, - MinHTLC: btcutil.Amount(edge.MinHTLC), - FeeBaseMSat: btcutil.Amount(edge.FeeBaseMsat), - FeeProportionalMillionths: btcutil.Amount(edge.FeeRate), + MinHTLC: lnwire.MilliSatoshi(edge.MinHTLC), + FeeBaseMSat: lnwire.MilliSatoshi(edge.FeeBaseMsat), + FeeProportionalMillionths: lnwire.MilliSatoshi(edge.FeeRate), } // As the graph itself is directed, we need to insert two edges @@ -312,7 +313,7 @@ func TestBasicGraphPathFinding(t *testing.T) { // finding. const startingHeight = 100 - const paymentAmt = btcutil.Amount(100) + paymentAmt := lnwire.NewMSatFromSatoshis(100) target := aliases["sophon"] path, err := findPath(graph, sourceNode, target, ignoredVertexes, ignoredEdges, paymentAmt) @@ -465,7 +466,7 @@ func TestKShortestPathFinding(t *testing.T) { // ji. Our algorithm should properly find both paths, and also rank // them in order of their total "distance". - const paymentAmt = btcutil.Amount(100) + paymentAmt := lnwire.NewMSatFromSatoshis(100) target := aliases["luoji"] paths, err := findPaths(graph, sourceNode, target, paymentAmt) if err != nil { @@ -523,7 +524,7 @@ func TestNewRoutePathTooLong(t *testing.T) { ignoredEdges := make(map[uint64]struct{}) ignoredVertexes := make(map[vertex]struct{}) - const paymentAmt = btcutil.Amount(100) + paymentAmt := lnwire.NewMSatFromSatoshis(100) // We start by confirminig that routing a payment 20 hops away is possible. // Alice should be able to find a valid route to ursula. diff --git a/routing/router.go b/routing/router.go index 72b873b91..7ad190df3 100644 --- a/routing/router.go +++ b/routing/router.go @@ -71,19 +71,16 @@ type ChannelGraphSource interface { // FeeSchema is the set fee configuration for a Lighting Node on the network. // Using the coefficients described within he schema, the required fee to // forward outgoing payments can be derived. -// -// TODO(roasbeef): should be in switch instead? type FeeSchema struct { - // TODO(rosbeef): all these should be in msat instead - - // BaseFee is the base amount that will be chained for ANY payment - // forwarded. - BaseFee btcutil.Amount + // BaseFee is the base amount of milli-satoshis that will be chained + // for ANY payment forwarded. + BaseFee lnwire.MilliSatoshi // FeeRate is the rate that will be charged for forwarding payments. - // The fee rate has a granularity of 1/1000 th of a mili-satoshi, or a - // millionth of a satoshi. - FeeRate btcutil.Amount + // This value should be interpreted as the numerator for a fraction + // whose denominator is 1 million. As a result the effective fee rate + // charged per mSAT will be: (amount * FeeRate/1,000,000) + FeeRate uint32 } // Config defines the configuration for the ChannelRouter. ALL elements within @@ -105,11 +102,6 @@ type Config struct { // we need in order to properly maintain the channel graph. ChainView chainview.FilteredChainView - // FeeSchema is the set fee schema that will be announced on to the - // network. - // TODO(roasbeef): should either be in discovery or switch - FeeSchema *FeeSchema - // SendToSwitch 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 @@ -123,12 +115,12 @@ type Config struct { // amount. We required the target amount as that will influence the available // set of paths for a payment. type routeTuple struct { - amt btcutil.Amount + amt lnwire.MilliSatoshi dest [33]byte } // newRouteTuple creates a new route tuple from the target and amount. -func newRouteTuple(amt btcutil.Amount, dest *btcec.PublicKey) routeTuple { +func newRouteTuple(amt lnwire.MilliSatoshi, dest *btcec.PublicKey) routeTuple { r := routeTuple{ amt: amt, } @@ -388,6 +380,8 @@ func (r *ChannelRouter) syncGraphWithChain() error { func (r *ChannelRouter) networkHandler() { defer r.wg.Done() + // TODO(roasbeef): ticker to check if should prune in two weeks or not + for { select { // A new fully validated network update has just arrived. As a @@ -812,9 +806,10 @@ type routingMsg struct { // required fee and time lock values running backwards along the route. The // route that will be ranked the highest is the one with the lowest cumulative // fee along the route. -func (r *ChannelRouter) FindRoutes(target *btcec.PublicKey, amt btcutil.Amount) ([]*Route, error) { - dest := target.SerializeCompressed() +func (r *ChannelRouter) FindRoutes(target *btcec.PublicKey, + amt lnwire.MilliSatoshi) ([]*Route, error) { + dest := target.SerializeCompressed() log.Debugf("Searching for path to %x, sending %v", dest, amt) // We can short circuit the routing by opportunistically checking to @@ -953,9 +948,8 @@ type LightningPayment struct { Target *btcec.PublicKey // Amount is the value of the payment to send through the network in - // satoshis. - // TODO(roasbeef): this should be milli satoshis - Amount btcutil.Amount + // milli-satoshis. + Amount lnwire.MilliSatoshi // PaymentHash is the r-hash value to use within the HTLC extended to // the first hop. diff --git a/routing/router_test.go b/routing/router_test.go index 662ba7262..ef33bd490 100644 --- a/routing/router_test.go +++ b/routing/router_test.go @@ -15,7 +15,6 @@ import ( "github.com/lightningnetwork/lightning-onion" "github.com/lightningnetwork/lnd/lnwire" "github.com/roasbeef/btcd/btcec" - "github.com/roasbeef/btcutil" ) type testCtx struct { @@ -126,7 +125,7 @@ func TestFindRoutesFeeSorting(t *testing.T) { // selection. // Execute a query for all possible routes between roasbeef and luo ji. - const paymentAmt = btcutil.Amount(100) + paymentAmt := lnwire.NewMSatFromSatoshis(100) target := ctx.aliases["luoji"] routes, err := ctx.router.FindRoutes(target, paymentAmt) if err != nil { @@ -166,7 +165,7 @@ func TestSendPaymentRouteFailureFallback(t *testing.T) { var payHash [32]byte payment := LightningPayment{ Target: ctx.aliases["luoji"], - Amount: btcutil.Amount(1000), + Amount: lnwire.NewMSatFromSatoshis(1000), PaymentHash: payHash, } @@ -341,7 +340,8 @@ func TestAddEdgeUnknownVertexes(t *testing.T) { // that the nodes are found after the fact. fundingTx, _, chanID, err := createChannelEdge(ctx, bitcoinKey1.SerializeCompressed(), - bitcoinKey2.SerializeCompressed(), 10000, 500) + bitcoinKey2.SerializeCompressed(), + 10000, 500) if err != nil { t.Fatalf("unable to create channel edge: %v", err) } @@ -370,9 +370,9 @@ func TestAddEdgeUnknownVertexes(t *testing.T) { ChannelID: edge.ChannelID, LastUpdate: time.Now(), TimeLockDelta: 10, - MinHTLC: btcutil.Amount(1), - FeeBaseMSat: btcutil.Amount(10), - FeeProportionalMillionths: btcutil.Amount(10000), + MinHTLC: 1, + FeeBaseMSat: 10, + FeeProportionalMillionths: 10000, } edgePolicy.Flags = 0 @@ -386,9 +386,9 @@ func TestAddEdgeUnknownVertexes(t *testing.T) { ChannelID: edge.ChannelID, LastUpdate: time.Now(), TimeLockDelta: 10, - MinHTLC: btcutil.Amount(1), - FeeBaseMSat: btcutil.Amount(10), - FeeProportionalMillionths: btcutil.Amount(10000), + MinHTLC: 1, + FeeBaseMSat: 10, + FeeProportionalMillionths: 10000, } edgePolicy.Flags = 1 @@ -466,9 +466,9 @@ func TestAddEdgeUnknownVertexes(t *testing.T) { ChannelID: edge.ChannelID, LastUpdate: time.Now(), TimeLockDelta: 10, - MinHTLC: btcutil.Amount(1), - FeeBaseMSat: btcutil.Amount(10), - FeeProportionalMillionths: btcutil.Amount(10000), + MinHTLC: 1, + FeeBaseMSat: 10, + FeeProportionalMillionths: 10000, } edgePolicy.Flags = 0 @@ -481,9 +481,9 @@ func TestAddEdgeUnknownVertexes(t *testing.T) { ChannelID: edge.ChannelID, LastUpdate: time.Now(), TimeLockDelta: 10, - MinHTLC: btcutil.Amount(1), - FeeBaseMSat: btcutil.Amount(10), - FeeProportionalMillionths: btcutil.Amount(10000), + MinHTLC: 1, + FeeBaseMSat: 10, + FeeProportionalMillionths: 10000, } edgePolicy.Flags = 1 @@ -492,7 +492,7 @@ func TestAddEdgeUnknownVertexes(t *testing.T) { } // We should now be able to find one route to node 2. - const paymentAmt = btcutil.Amount(100) + paymentAmt := lnwire.NewMSatFromSatoshis(100) targetNode := priv2.PubKey() routes, err := ctx.router.FindRoutes(targetNode, paymentAmt) if err != nil {