routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
package routing
|
|
|
|
|
|
|
|
import (
|
2017-01-23 01:39:18 +03:00
|
|
|
"bytes"
|
2017-02-07 01:54:50 +03:00
|
|
|
"fmt"
|
2017-03-21 04:25:54 +03:00
|
|
|
"sort"
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
"sync"
|
|
|
|
"sync/atomic"
|
2017-10-03 08:03:18 +03:00
|
|
|
"time"
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
|
2017-04-14 23:14:54 +03:00
|
|
|
"github.com/boltdb/bolt"
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
"github.com/davecgh/go-spew/spew"
|
|
|
|
"github.com/lightningnetwork/lnd/channeldb"
|
2017-10-11 05:48:44 +03:00
|
|
|
"github.com/lightningnetwork/lnd/htlcswitch"
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
"github.com/lightningnetwork/lnd/lnwallet"
|
|
|
|
"github.com/lightningnetwork/lnd/lnwire"
|
2017-05-11 03:22:26 +03:00
|
|
|
"github.com/lightningnetwork/lnd/routing/chainview"
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
"github.com/roasbeef/btcd/btcec"
|
|
|
|
"github.com/roasbeef/btcd/wire"
|
|
|
|
"github.com/roasbeef/btcutil"
|
2017-02-02 05:29:46 +03:00
|
|
|
|
2017-06-29 16:40:45 +03:00
|
|
|
"crypto/sha256"
|
|
|
|
|
2017-03-19 21:40:25 +03:00
|
|
|
"github.com/go-errors/errors"
|
2017-02-02 05:29:46 +03:00
|
|
|
"github.com/lightningnetwork/lightning-onion"
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
)
|
|
|
|
|
2017-10-19 07:59:06 +03:00
|
|
|
const (
|
|
|
|
// DefaultFinalCLTVDelta is the default value to be used as the final
|
|
|
|
// CLTV delta for a route if one is unspecified.
|
|
|
|
DefaultFinalCLTVDelta = 9
|
|
|
|
)
|
|
|
|
|
2017-04-01 15:33:17 +03:00
|
|
|
// ChannelGraphSource represent the source of information about the topology of
|
|
|
|
// lightning network, it responsible for addition of nodes, edges
|
2017-03-19 21:40:25 +03:00
|
|
|
// and applying edges updates, return the current block with with out
|
|
|
|
// topology is synchronized.
|
|
|
|
type ChannelGraphSource interface {
|
2017-07-14 22:32:00 +03:00
|
|
|
// AddNode is used to add information about a node to the router
|
|
|
|
// database. If the node with this pubkey is not present in an existing
|
|
|
|
// channel, it will be ignored.
|
2017-03-19 21:40:25 +03:00
|
|
|
AddNode(node *channeldb.LightningNode) error
|
|
|
|
|
|
|
|
// AddEdge is used to add edge/channel to the topology of the router,
|
|
|
|
// after all information about channel will be gathered this
|
|
|
|
// edge/channel might be used in construction of payment path.
|
|
|
|
AddEdge(edge *channeldb.ChannelEdgeInfo) error
|
|
|
|
|
2017-04-01 15:33:17 +03:00
|
|
|
// AddProof updates the channel edge info with proof which is needed to
|
|
|
|
// properly announce the edge to the rest of the network.
|
2017-03-27 20:00:38 +03:00
|
|
|
AddProof(chanID lnwire.ShortChannelID, proof *channeldb.ChannelAuthProof) error
|
|
|
|
|
2017-04-01 15:33:17 +03:00
|
|
|
// UpdateEdge is used to update edge information, without this message
|
|
|
|
// edge considered as not fully constructed.
|
2017-03-19 21:40:25 +03:00
|
|
|
UpdateEdge(policy *channeldb.ChannelEdgePolicy) error
|
|
|
|
|
2017-04-01 15:33:17 +03:00
|
|
|
// ForAllOutgoingChannels is used to iterate over all channels
|
|
|
|
// eminating from the "source" node which is the center of the
|
|
|
|
// star-graph.
|
2017-08-22 09:58:59 +03:00
|
|
|
ForAllOutgoingChannels(cb func(c *channeldb.ChannelEdgeInfo,
|
|
|
|
e *channeldb.ChannelEdgePolicy) error) error
|
2017-03-19 21:40:25 +03:00
|
|
|
|
|
|
|
// CurrentBlockHeight returns the block height from POV of the router
|
|
|
|
// subsystem.
|
|
|
|
CurrentBlockHeight() (uint32, error)
|
|
|
|
|
2017-03-30 04:01:28 +03:00
|
|
|
// GetChannelByID return the channel by the channel id.
|
|
|
|
GetChannelByID(chanID lnwire.ShortChannelID) (*channeldb.ChannelEdgeInfo,
|
|
|
|
*channeldb.ChannelEdgePolicy, *channeldb.ChannelEdgePolicy, error)
|
|
|
|
|
2017-04-01 15:33:17 +03:00
|
|
|
// ForEachNode is used to iterate over every node in the known graph.
|
2017-03-19 21:40:25 +03:00
|
|
|
ForEachNode(func(node *channeldb.LightningNode) error) error
|
|
|
|
|
2017-04-01 15:33:17 +03:00
|
|
|
// ForEachChannel is used to iterate over every channel in the known
|
|
|
|
// graph.
|
2017-03-19 21:40:25 +03:00
|
|
|
ForEachChannel(func(chanInfo *channeldb.ChannelEdgeInfo,
|
|
|
|
e1, e2 *channeldb.ChannelEdgePolicy) error) error
|
|
|
|
}
|
|
|
|
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
// 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.
|
|
|
|
type FeeSchema struct {
|
2017-08-22 09:43:20 +03:00
|
|
|
// BaseFee is the base amount of milli-satoshis that will be chained
|
|
|
|
// for ANY payment forwarded.
|
|
|
|
BaseFee lnwire.MilliSatoshi
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
|
|
|
|
// FeeRate is the rate that will be charged for forwarding payments.
|
2017-08-22 09:43:20 +03:00
|
|
|
// This value should be interpreted as the numerator for a fraction
|
2017-10-17 04:13:52 +03:00
|
|
|
// (fixed point arithmetic) whose denominator is 1 million. As a result
|
|
|
|
// the effective fee rate charged per mSAT will be: (amount *
|
|
|
|
// FeeRate/1,000,000).
|
2017-08-22 09:43:20 +03:00
|
|
|
FeeRate uint32
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Config defines the configuration for the ChannelRouter. ALL elements within
|
|
|
|
// the configuration MUST be non-nil for the ChannelRouter to carry out its
|
|
|
|
// duties.
|
|
|
|
type Config struct {
|
|
|
|
// Graph is the channel graph that the ChannelRouter will use to gather
|
|
|
|
// metrics from and also to carry out path finding queries.
|
|
|
|
// TODO(roasbeef): make into an interface
|
|
|
|
Graph *channeldb.ChannelGraph
|
|
|
|
|
|
|
|
// Chain is the router's source to the most up-to-date blockchain data.
|
|
|
|
// All incoming advertised channels will be checked against the chain
|
|
|
|
// to ensure that the channels advertised are still open.
|
|
|
|
Chain lnwallet.BlockChainIO
|
|
|
|
|
2017-05-11 03:22:26 +03:00
|
|
|
// ChainView is an instance of a FilteredChainView which is used to
|
|
|
|
// watch the sub-set of the UTXO set (the set of active channels) that
|
|
|
|
// we need in order to properly maintain the channel graph.
|
|
|
|
ChainView chainview.FilteredChainView
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
|
2017-02-02 05:29:46 +03:00
|
|
|
// 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
|
|
|
|
// payment was unsuccessful.
|
2017-06-29 16:40:45 +03:00
|
|
|
SendToSwitch func(firstHop *btcec.PublicKey, htlcAdd *lnwire.UpdateAddHTLC,
|
|
|
|
circuit *sphinx.Circuit) ([sha256.Size]byte, error)
|
2017-10-05 05:39:38 +03:00
|
|
|
|
|
|
|
// ChannelPruneExpiry is the duration used to determine if a channel
|
|
|
|
// should be pruned or not. If the delta between now and when the
|
|
|
|
// channel was last updated is greater than ChannelPruneExpiry, then
|
|
|
|
// the channel is marked as a zombie channel eligible for pruning.
|
|
|
|
ChannelPruneExpiry time.Duration
|
|
|
|
|
|
|
|
// GraphPruneInterval is used as an interval to determine how often we
|
|
|
|
// should examine the channel graph to garbage collect zombie channels.
|
|
|
|
GraphPruneInterval time.Duration
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
}
|
|
|
|
|
2017-03-21 07:28:39 +03:00
|
|
|
// routeTuple is an entry within the ChannelRouter's route cache. We cache
|
|
|
|
// prospective routes based on first the destination, and then the target
|
|
|
|
// amount. We required the target amount as that will influence the available
|
|
|
|
// set of paths for a payment.
|
|
|
|
type routeTuple struct {
|
2017-08-22 09:43:20 +03:00
|
|
|
amt lnwire.MilliSatoshi
|
2017-03-21 07:28:39 +03:00
|
|
|
dest [33]byte
|
|
|
|
}
|
|
|
|
|
|
|
|
// newRouteTuple creates a new route tuple from the target and amount.
|
2017-10-03 07:58:34 +03:00
|
|
|
func newRouteTuple(amt lnwire.MilliSatoshi, dest []byte) routeTuple {
|
2017-03-21 07:28:39 +03:00
|
|
|
r := routeTuple{
|
|
|
|
amt: amt,
|
|
|
|
}
|
2017-10-03 07:58:34 +03:00
|
|
|
copy(r.dest[:], dest)
|
2017-03-21 07:28:39 +03:00
|
|
|
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
// ChannelRouter is the layer 3 router within the Lightning stack. Below the
|
|
|
|
// ChannelRouter is the HtlcSwitch, and below that is the Bitcoin blockchain
|
|
|
|
// itself. The primary role of the ChannelRouter is to respond to queries for
|
|
|
|
// potential routes that can support a payment amount, and also general graph
|
2017-10-17 04:13:52 +03:00
|
|
|
// reachability questions. The router will prune the channel graph
|
|
|
|
// automatically as new blocks are discovered which spend certain known funding
|
|
|
|
// outpoints, thereby closing their respective channels.
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
type ChannelRouter struct {
|
2017-03-09 01:27:46 +03:00
|
|
|
ntfnClientCounter uint64
|
|
|
|
|
|
|
|
started uint32
|
|
|
|
stopped uint32
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
|
2017-05-11 03:22:26 +03:00
|
|
|
bestHeight uint32
|
|
|
|
|
2017-02-03 04:44:13 +03:00
|
|
|
// cfg is a copy of the configuration struct that the ChannelRouter was
|
|
|
|
// initialized with.
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
cfg *Config
|
|
|
|
|
2017-10-23 03:29:55 +03:00
|
|
|
// selfNode is the center of the star-graph centered around the
|
|
|
|
// ChannelRouter. The ChannelRouter uses this node as a starting point
|
|
|
|
// when doing any path finding.
|
|
|
|
selfNode *channeldb.LightningNode
|
|
|
|
|
2017-03-21 07:28:39 +03:00
|
|
|
// routeCache is a map that caches the k-shortest paths from ourselves
|
|
|
|
// to a given target destination for a particular payment amount. This
|
|
|
|
// map is used as an optimization to speed up subsequent payments to a
|
|
|
|
// particular destination. This map will be cleared each time a new
|
|
|
|
// channel announcement is accepted, or a new block arrives that
|
|
|
|
// results in channels being closed.
|
|
|
|
//
|
|
|
|
// TODO(roasbeef): make LRU
|
|
|
|
routeCacheMtx sync.RWMutex
|
|
|
|
routeCache map[routeTuple][]*Route
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
|
2017-02-03 04:44:13 +03:00
|
|
|
// newBlocks is a channel in which new blocks connected to the end of
|
2017-10-02 18:54:29 +03:00
|
|
|
// the main chain are sent over, and blocks updated after a call to
|
|
|
|
// UpdateFilter.
|
2017-05-11 03:22:26 +03:00
|
|
|
newBlocks <-chan *chainview.FilteredBlock
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
|
2017-10-02 18:54:29 +03:00
|
|
|
// staleBlocks is a channel in which blocks disconnected fromt the end
|
|
|
|
// of our currently known best chain are sent over.
|
|
|
|
staleBlocks <-chan *chainview.FilteredBlock
|
|
|
|
|
2017-03-19 21:40:25 +03:00
|
|
|
// networkUpdates is a channel that carries new topology updates
|
|
|
|
// messages from outside the ChannelRouter to be processed by the
|
|
|
|
// networkHandler.
|
|
|
|
networkUpdates chan *routingMsg
|
2017-02-03 04:44:13 +03:00
|
|
|
|
2017-03-09 01:27:46 +03:00
|
|
|
// topologyClients maps a client's unique notification ID to a
|
|
|
|
// topologyClient client that contains its notification dispatch
|
|
|
|
// channel.
|
2017-06-25 15:48:47 +03:00
|
|
|
topologyClients map[uint64]*topologyClient
|
2017-03-09 01:27:46 +03:00
|
|
|
|
|
|
|
// ntfnClientUpdates is a channel that's used to send new updates to
|
|
|
|
// topology notification clients to the ChannelRouter. Updates either
|
|
|
|
// add a new notification client, or cancel notifications for an
|
|
|
|
// existing client.
|
|
|
|
ntfnClientUpdates chan *topologyClientUpdate
|
|
|
|
|
routing: modify SendPayment loop to be lazy, iterative, and use missionControl
In this commit we modify the SendPayment loop to optimize for
time-to-first-payment-success-or-failure. The prior logic would first
attempt to find at least 100 routes to the destination, then
iteratively prune them away as errors were encountered. In this commit,
we modify this approach to instead take a lazy approach: we first find
the current “best” path, attempt to send to that, and if an error
occurs we prune a section of the graph by reporting to missionControl,
then continue.
With this new approach, if the first known path has sufficient
capacity, and is available, then the payment speed is greatly improved
from the PoV of users. Additionally, we avoid the excessive computation
of crawling most of the graph in the k-shortest paths loop. With the
decay on missionControl, all routes will now feed information into the
central knowledge hung, allowing all payments to iteratively find out
the inactive portions of the payment graph.
2017-10-17 05:05:39 +03:00
|
|
|
// missionControl is a shared memory of sorts that executions of
|
|
|
|
// payment path finding use in order to remember which vertexes/edges
|
|
|
|
// were pruned from prior attempts. During SendPayment execution,
|
|
|
|
// errors sent by nodes are mapped into a vertex or edge to be pruned.
|
|
|
|
// Each run will then take into account this set of pruned
|
|
|
|
// vertexes/edges to reduce route failure and pass on graph information
|
|
|
|
// gained to the next execution.
|
|
|
|
missionControl *missionControl
|
|
|
|
|
2017-03-09 01:27:46 +03:00
|
|
|
sync.RWMutex
|
|
|
|
|
|
|
|
quit chan struct{}
|
|
|
|
wg sync.WaitGroup
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
}
|
|
|
|
|
2017-10-11 05:48:44 +03:00
|
|
|
// A compile time check to ensure ChannelRouter implements the
|
|
|
|
// ChannelGraphSource interface.
|
2017-03-19 21:40:25 +03:00
|
|
|
var _ ChannelGraphSource = (*ChannelRouter)(nil)
|
|
|
|
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
// New creates a new instance of the ChannelRouter with the specified
|
|
|
|
// configuration parameters. As part of initialization, if the router detects
|
|
|
|
// that the channel graph isn't fully in sync with the latest UTXO (since the
|
|
|
|
// channel graph is a subset of the UTXO set) set, then the router will proceed
|
|
|
|
// to fully sync to the latest state of the UTXO set.
|
|
|
|
func New(cfg Config) (*ChannelRouter, error) {
|
|
|
|
|
2017-10-23 03:29:55 +03:00
|
|
|
selfNode, err := cfg.Graph.SourceNode()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
return &ChannelRouter{
|
2017-03-19 21:40:25 +03:00
|
|
|
cfg: &cfg,
|
|
|
|
networkUpdates: make(chan *routingMsg),
|
2017-06-25 15:48:47 +03:00
|
|
|
topologyClients: make(map[uint64]*topologyClient),
|
2017-03-19 21:40:25 +03:00
|
|
|
ntfnClientUpdates: make(chan *topologyClientUpdate),
|
2017-10-18 05:41:46 +03:00
|
|
|
missionControl: newMissionControl(cfg.Graph, selfNode),
|
2017-10-23 03:29:55 +03:00
|
|
|
selfNode: selfNode,
|
2017-03-19 21:40:25 +03:00
|
|
|
routeCache: make(map[routeTuple][]*Route),
|
|
|
|
quit: make(chan struct{}),
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Start launches all the goroutines the ChannelRouter requires to carry out
|
|
|
|
// its duties. If the router has already been started, then this method is a
|
|
|
|
// noop.
|
|
|
|
func (r *ChannelRouter) Start() error {
|
|
|
|
if !atomic.CompareAndSwapUint32(&r.started, 0, 1) {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Tracef("Channel Router starting")
|
|
|
|
|
2017-05-11 03:22:26 +03:00
|
|
|
// First, we'll start the chain view instance (if it isn't already
|
|
|
|
// started).
|
|
|
|
if err := r.cfg.ChainView.Start(); err != nil {
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
return err
|
|
|
|
}
|
2017-05-11 03:22:26 +03:00
|
|
|
|
|
|
|
// Once the instance is active, we'll fetch the channel we'll receive
|
|
|
|
// notifications over.
|
|
|
|
r.newBlocks = r.cfg.ChainView.FilteredBlocks()
|
2017-10-02 18:54:29 +03:00
|
|
|
r.staleBlocks = r.cfg.ChainView.DisconnectedBlocks()
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
|
|
|
|
// Before we begin normal operation of the router, we first need to
|
|
|
|
// synchronize the channel graph to the latest state of the UTXO set.
|
|
|
|
if err := r.syncGraphWithChain(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2017-05-11 03:22:26 +03:00
|
|
|
// Once we've concluded our manual block pruning, we'll constrcut and
|
|
|
|
// apply a fresh chain filter to the active FilteredChainView instance.
|
|
|
|
channelView, err := r.cfg.Graph.ChannelView()
|
|
|
|
if err != nil && err != channeldb.ErrGraphNoEdgesFound {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
log.Infof("Filtering chain using %v channels active", len(channelView))
|
|
|
|
err = r.cfg.ChainView.UpdateFilter(channelView, r.bestHeight)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
r.wg.Add(1)
|
|
|
|
go r.networkHandler()
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Stop signals the ChannelRouter to gracefully halt all routines. This method
|
|
|
|
// will *block* until all goroutines have excited. If the channel router has
|
|
|
|
// already stopped then this method will return immediately.
|
|
|
|
func (r *ChannelRouter) Stop() error {
|
|
|
|
if !atomic.CompareAndSwapUint32(&r.stopped, 0, 1) {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Infof("Channel Router shutting down")
|
|
|
|
|
2017-05-11 03:22:26 +03:00
|
|
|
if err := r.cfg.ChainView.Stop(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
close(r.quit)
|
|
|
|
r.wg.Wait()
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// syncGraphWithChain attempts to synchronize the current channel graph with
|
|
|
|
// the latest UTXO set state. This process involves pruning from the channel
|
|
|
|
// graph any channels which have been closed by spending their funding output
|
|
|
|
// since we've been down.
|
|
|
|
func (r *ChannelRouter) syncGraphWithChain() error {
|
|
|
|
// First, we'll need to check to see if we're already in sync with the
|
|
|
|
// latest state of the UTXO set.
|
|
|
|
bestHash, bestHeight, err := r.cfg.Chain.GetBestBlock()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-05-11 03:22:26 +03:00
|
|
|
r.bestHeight = uint32(bestHeight)
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
pruneHash, pruneHeight, err := r.cfg.Graph.PruneTip()
|
|
|
|
if err != nil {
|
|
|
|
switch {
|
|
|
|
// If the graph has never been pruned, or hasn't fully been
|
|
|
|
// created yet, then we don't treat this as an explicit error.
|
|
|
|
case err == channeldb.ErrGraphNeverPruned:
|
|
|
|
case err == channeldb.ErrGraphNotFound:
|
|
|
|
default:
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Infof("Prune tip for Channel Graph: height=%v, hash=%v", pruneHeight,
|
|
|
|
pruneHash)
|
|
|
|
|
|
|
|
switch {
|
|
|
|
|
|
|
|
// If the graph has never been pruned, then we can exit early as this
|
|
|
|
// entails it's being created for the first time and hasn't seen any
|
|
|
|
// block or created channels.
|
|
|
|
case pruneHeight == 0 || pruneHash == nil:
|
|
|
|
return nil
|
|
|
|
|
|
|
|
// If the block hashes and heights match exactly, then we don't need to
|
|
|
|
// prune the channel graph as we're already fully in sync.
|
|
|
|
case bestHash.IsEqual(pruneHash) && uint32(bestHeight) == pruneHeight:
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-10-02 18:54:29 +03:00
|
|
|
// If the main chain blockhash at prune height is different from the
|
|
|
|
// prune hash, this might indicate the database is on a stale branch.
|
|
|
|
mainBlockHash, err := r.cfg.Chain.GetBlockHash(int64(pruneHeight))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// While we are on a stale branch of the chain, walk backwards to find
|
|
|
|
// first common block.
|
|
|
|
for !pruneHash.IsEqual(mainBlockHash) {
|
|
|
|
log.Infof("channel graph is stale. Disconnecting block %v "+
|
|
|
|
"(hash=%v)", pruneHeight, pruneHash)
|
|
|
|
// Prune the graph for every channel that was opened at height
|
|
|
|
// >= pruneHeigth.
|
|
|
|
_, err := r.cfg.Graph.DisconnectBlockAtHeight(pruneHeight)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
pruneHash, pruneHeight, err = r.cfg.Graph.PruneTip()
|
|
|
|
if err != nil {
|
|
|
|
switch {
|
|
|
|
// If at this point the graph has never been pruned, we
|
|
|
|
// can exit as this entails we are back to the point
|
|
|
|
// where it hasn't seen any block or created channels,
|
|
|
|
// alas there's nothing left to prune.
|
|
|
|
case err == channeldb.ErrGraphNeverPruned:
|
|
|
|
return nil
|
|
|
|
case err == channeldb.ErrGraphNotFound:
|
|
|
|
return nil
|
|
|
|
default:
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mainBlockHash, err = r.cfg.Chain.GetBlockHash(int64(pruneHeight))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
log.Infof("Syncing channel graph from height=%v (hash=%v) to height=%v "+
|
|
|
|
"(hash=%v)", pruneHeight, pruneHash, bestHeight, bestHash)
|
|
|
|
|
|
|
|
// If we're not yet caught up, then we'll walk forward in the chain in
|
|
|
|
// the chain pruning the channel graph with each new block in the chain
|
|
|
|
// that hasn't yet been consumed by the channel graph.
|
|
|
|
var numChansClosed uint32
|
|
|
|
for nextHeight := pruneHeight + 1; nextHeight <= uint32(bestHeight); nextHeight++ {
|
2017-05-11 03:22:26 +03:00
|
|
|
// Using the next height, request a manual block pruning from
|
|
|
|
// the chainview for the particular block hash.
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
nextHash, err := r.cfg.Chain.GetBlockHash(int64(nextHeight))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-05-11 03:22:26 +03:00
|
|
|
filterBlock, err := r.cfg.ChainView.FilterBlock(nextHash)
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// We're only interested in all prior outputs that've been
|
|
|
|
// spent in the block, so collate all the referenced previous
|
|
|
|
// outpoints within each tx and input.
|
|
|
|
var spentOutputs []*wire.OutPoint
|
2017-05-11 03:22:26 +03:00
|
|
|
for _, tx := range filterBlock.Transactions {
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
for _, txIn := range tx.TxIn {
|
|
|
|
spentOutputs = append(spentOutputs,
|
|
|
|
&txIn.PreviousOutPoint)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// With the spent outputs gathered, attempt to prune the
|
|
|
|
// channel graph, also passing in the hash+height of the block
|
|
|
|
// being pruned so the prune tip can be updated.
|
2017-03-09 01:27:46 +03:00
|
|
|
closedChans, err := r.cfg.Graph.PruneGraph(spentOutputs, nextHash,
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
nextHeight)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2017-03-09 01:27:46 +03:00
|
|
|
numClosed := uint32(len(closedChans))
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
log.Infof("Block %v (height=%v) closed %v channels",
|
|
|
|
nextHash, nextHeight, numClosed)
|
|
|
|
|
|
|
|
numChansClosed += numClosed
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Infof("Graph pruning complete: %v channels we're closed since "+
|
|
|
|
"height %v", numChansClosed, pruneHeight)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// networkHandler is the primary goroutine for the ChannelRouter. The roles of
|
|
|
|
// this goroutine include answering queries related to the state of the
|
2017-03-19 21:40:25 +03:00
|
|
|
// network, pruning the graph on new block notification, applying network
|
|
|
|
// updates, and registering new topology clients.
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
//
|
|
|
|
// NOTE: This MUST be run as a goroutine.
|
|
|
|
func (r *ChannelRouter) networkHandler() {
|
|
|
|
defer r.wg.Done()
|
|
|
|
|
2017-10-05 05:39:38 +03:00
|
|
|
graphPruneTicker := time.NewTicker(r.cfg.GraphPruneInterval)
|
|
|
|
defer graphPruneTicker.Stop()
|
2017-08-22 09:43:20 +03:00
|
|
|
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
for {
|
|
|
|
select {
|
2017-03-19 21:40:25 +03:00
|
|
|
// A new fully validated network update has just arrived. As a
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
// result we'll modify the channel graph accordingly depending
|
|
|
|
// on the exact type of the message.
|
2017-03-19 21:40:25 +03:00
|
|
|
case updateMsg := <-r.networkUpdates:
|
|
|
|
// Process the routing update to determine if this is
|
|
|
|
// either a new update from our PoV or an update to a
|
2017-10-17 04:13:52 +03:00
|
|
|
// prior vertex/edge we previously accepted.
|
2017-03-19 21:40:25 +03:00
|
|
|
err := r.processUpdate(updateMsg.msg)
|
|
|
|
updateMsg.err <- err
|
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
2017-03-09 01:27:46 +03:00
|
|
|
|
2017-10-17 04:13:52 +03:00
|
|
|
// Send off a new notification for the newly accepted
|
|
|
|
// update.
|
2017-03-19 21:40:25 +03:00
|
|
|
topChange := &TopologyChange{}
|
|
|
|
err = addToTopologyChange(r.cfg.Graph, topChange,
|
|
|
|
updateMsg.msg)
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("unable to update topology "+
|
|
|
|
"change notification: %v", err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if !topChange.isEmpty() {
|
|
|
|
r.notifyTopologyChange(topChange)
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO(roasbeef): remove all unconnected vertexes
|
|
|
|
// after N blocks pass with no corresponding
|
|
|
|
// announcements.
|
|
|
|
|
2017-10-02 18:54:29 +03:00
|
|
|
case chainUpdate, ok := <-r.staleBlocks:
|
|
|
|
// If the channel has been closed, then this indicates
|
|
|
|
// the daemon is shutting down, so we exit ourselves.
|
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Since this block is stale, we update our best height
|
|
|
|
// to the previous block.
|
|
|
|
blockHeight := uint32(chainUpdate.Height)
|
|
|
|
r.bestHeight = blockHeight - 1
|
|
|
|
|
|
|
|
// Update the channel graph to reflect that this block
|
|
|
|
// was disconnected.
|
|
|
|
_, err := r.cfg.Graph.DisconnectBlockAtHeight(blockHeight)
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("unable to prune graph with stale "+
|
|
|
|
"block: %v", err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
// Invalidate the route cache, as some channels might
|
|
|
|
// not be confirmed anymore.
|
|
|
|
r.routeCacheMtx.Lock()
|
|
|
|
r.routeCache = make(map[routeTuple][]*Route)
|
|
|
|
r.routeCacheMtx.Unlock()
|
|
|
|
|
|
|
|
// TODO(halseth): notify client about the reorg?
|
|
|
|
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
// A new block has arrived, so we can prune the channel graph
|
|
|
|
// of any channels which were closed in the block.
|
2017-05-11 03:22:26 +03:00
|
|
|
case chainUpdate, ok := <-r.newBlocks:
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
// If the channel has been closed, then this indicates
|
|
|
|
// the daemon is shutting down, so we exit ourselves.
|
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2017-02-03 04:44:13 +03:00
|
|
|
// Once a new block arrives, we update our running
|
|
|
|
// track of the height of the chain tip.
|
2017-05-11 03:22:26 +03:00
|
|
|
blockHeight := uint32(chainUpdate.Height)
|
|
|
|
r.bestHeight = blockHeight
|
2017-02-03 04:44:13 +03:00
|
|
|
log.Infof("Pruning channel graph using block %v (height=%v)",
|
2017-05-11 03:22:26 +03:00
|
|
|
chainUpdate.Hash, blockHeight)
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
|
|
|
|
// We're only interested in all prior outputs that've
|
|
|
|
// been spent in the block, so collate all the
|
|
|
|
// referenced previous outpoints within each tx and
|
|
|
|
// input.
|
|
|
|
var spentOutputs []*wire.OutPoint
|
2017-05-11 03:22:26 +03:00
|
|
|
for _, tx := range chainUpdate.Transactions {
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
for _, txIn := range tx.TxIn {
|
|
|
|
spentOutputs = append(spentOutputs,
|
|
|
|
&txIn.PreviousOutPoint)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// With the spent outputs gathered, attempt to prune
|
|
|
|
// the channel graph, also passing in the hash+height
|
|
|
|
// of the block being pruned so the prune tip can be
|
|
|
|
// updated.
|
2017-03-09 01:27:46 +03:00
|
|
|
chansClosed, err := r.cfg.Graph.PruneGraph(spentOutputs,
|
2017-05-11 03:22:26 +03:00
|
|
|
&chainUpdate.Hash, chainUpdate.Height)
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
if err != nil {
|
|
|
|
log.Errorf("unable to prune routing table: %v", err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Infof("Block %v (height=%v) closed %v channels",
|
2017-05-11 03:22:26 +03:00
|
|
|
chainUpdate.Hash, blockHeight, len(chansClosed))
|
2017-03-09 01:27:46 +03:00
|
|
|
|
2017-08-03 07:06:57 +03:00
|
|
|
// Invalidate the route cache as the block height has
|
|
|
|
// changed which will invalidate the HTLC timeouts we
|
|
|
|
// have crafted within each of the pre-computed routes.
|
|
|
|
//
|
|
|
|
// TODO(roasbeef): need to invalidate after each
|
|
|
|
// chan ann update?
|
|
|
|
// * can have map of chanID to routes involved, avoids
|
|
|
|
// full invalidation
|
2017-03-21 07:28:39 +03:00
|
|
|
r.routeCacheMtx.Lock()
|
|
|
|
r.routeCache = make(map[routeTuple][]*Route)
|
|
|
|
r.routeCacheMtx.Unlock()
|
|
|
|
|
2017-08-03 07:06:57 +03:00
|
|
|
if len(chansClosed) == 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2017-03-09 01:27:46 +03:00
|
|
|
// Notify all currently registered clients of the newly
|
|
|
|
// closed channels.
|
|
|
|
closeSummaries := createCloseSummaries(blockHeight, chansClosed...)
|
|
|
|
r.notifyTopologyChange(&TopologyChange{
|
|
|
|
ClosedChannels: closeSummaries,
|
|
|
|
})
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
|
2017-03-09 01:27:46 +03:00
|
|
|
// A new notification client update has arrived. We're either
|
|
|
|
// gaining a new client, or cancelling notifications for an
|
|
|
|
// existing client.
|
|
|
|
case ntfnUpdate := <-r.ntfnClientUpdates:
|
|
|
|
clientID := ntfnUpdate.clientID
|
|
|
|
|
|
|
|
if ntfnUpdate.cancel {
|
|
|
|
if client, ok := r.topologyClients[ntfnUpdate.clientID]; ok {
|
|
|
|
delete(r.topologyClients, clientID)
|
2017-06-25 15:31:41 +03:00
|
|
|
|
2017-03-09 01:27:46 +03:00
|
|
|
close(client.exit)
|
2017-06-25 15:31:41 +03:00
|
|
|
client.wg.Wait()
|
|
|
|
|
2017-05-16 04:47:18 +03:00
|
|
|
close(client.ntfnChan)
|
2017-03-09 01:27:46 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2017-06-25 15:48:47 +03:00
|
|
|
r.topologyClients[ntfnUpdate.clientID] = &topologyClient{
|
2017-03-09 01:27:46 +03:00
|
|
|
ntfnChan: ntfnUpdate.ntfnChan,
|
|
|
|
exit: make(chan struct{}),
|
|
|
|
}
|
|
|
|
|
2017-10-05 05:39:38 +03:00
|
|
|
// The graph prune ticker has ticked, so we'll examine the
|
|
|
|
// state of the known graph to filter out any zombie channels
|
|
|
|
// for pruning.
|
|
|
|
case <-graphPruneTicker.C:
|
|
|
|
|
|
|
|
var chansToPrune []wire.OutPoint
|
|
|
|
chanExpiry := r.cfg.ChannelPruneExpiry
|
|
|
|
|
|
|
|
log.Infof("Examining Channel Graph for zombie channels")
|
|
|
|
|
|
|
|
// First, we'll collect all the channels which are
|
|
|
|
// eligible for garbage collection due to being
|
|
|
|
// zombies.
|
|
|
|
filterPruneChans := func(info *channeldb.ChannelEdgeInfo,
|
|
|
|
e1, e2 *channeldb.ChannelEdgePolicy) error {
|
|
|
|
|
2017-10-17 04:13:52 +03:00
|
|
|
// We'll ensure that we don't attempt to prune
|
|
|
|
// our *own* channels from the graph, as in any
|
|
|
|
// case this shuold be re-advertised by the
|
|
|
|
// sub-system above us.
|
|
|
|
if info.NodeKey1.IsEqual(r.selfNode.PubKey) ||
|
|
|
|
info.NodeKey2.IsEqual(r.selfNode.PubKey) {
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-10-05 05:39:38 +03:00
|
|
|
// If *both* edges haven't been updated for a
|
|
|
|
// period of chanExpiry, then we'll mark the
|
|
|
|
// channel itself as eligible for graph
|
|
|
|
// pruning.
|
|
|
|
e1Zombie, e2Zombie := true, true
|
|
|
|
if e1 != nil {
|
|
|
|
e1Zombie = time.Since(e1.LastUpdate) >= chanExpiry
|
|
|
|
log.Tracef("Edge #1 of ChannelPoint(%v) "+
|
|
|
|
"last update: %v",
|
|
|
|
info.ChannelPoint, e1.LastUpdate)
|
|
|
|
}
|
|
|
|
if e2 != nil {
|
|
|
|
e2Zombie = time.Since(e2.LastUpdate) >= chanExpiry
|
|
|
|
log.Tracef("Edge #2 of ChannelPoint(%v) "+
|
|
|
|
"last update: %v",
|
|
|
|
info.ChannelPoint, e2.LastUpdate)
|
|
|
|
}
|
|
|
|
if e1Zombie && e2Zombie {
|
|
|
|
log.Infof("ChannelPoint(%v) is a "+
|
|
|
|
"zombie, collecting to prune",
|
|
|
|
info.ChannelPoint)
|
|
|
|
|
|
|
|
// TODO(roasbeef): add ability to
|
|
|
|
// delete single directional edge
|
|
|
|
chansToPrune = append(chansToPrune,
|
|
|
|
info.ChannelPoint)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
err := r.cfg.Graph.ForEachChannel(filterPruneChans)
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("Unable to local zombie chans: %v", err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Infof("Pruning %v Zombie Channels", len(chansToPrune))
|
|
|
|
|
|
|
|
// With the set zombie-like channels obtained, we'll do
|
|
|
|
// another pass to delete al zombie channels from the
|
|
|
|
// channel graph.
|
|
|
|
for _, chanToPrune := range chansToPrune {
|
|
|
|
log.Tracef("Pruning zombie chan ChannelPoint(%v)",
|
|
|
|
chanToPrune)
|
|
|
|
|
|
|
|
err := r.cfg.Graph.DeleteChannelEdge(&chanToPrune)
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("Unable to prune zombie "+
|
|
|
|
"chans: %v", err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
// The router has been signalled to exit, to we exit our main
|
|
|
|
// loop so the wait group can be decremented.
|
|
|
|
case <-r.quit:
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-19 21:40:25 +03:00
|
|
|
// processUpdate processes a new relate authenticated channel/edge, node or
|
2017-04-01 15:33:17 +03:00
|
|
|
// channel/edge update network update. If the update didn't affect the internal
|
|
|
|
// state of the draft due to either being out of date, invalid, or redundant,
|
|
|
|
// then error is returned.
|
2017-03-19 21:40:25 +03:00
|
|
|
func (r *ChannelRouter) processUpdate(msg interface{}) error {
|
2017-02-03 04:44:13 +03:00
|
|
|
|
2017-03-21 07:28:39 +03:00
|
|
|
var invalidateCache bool
|
|
|
|
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
switch msg := msg.(type) {
|
2017-03-19 21:40:25 +03:00
|
|
|
case *channeldb.LightningNode:
|
2017-07-14 22:32:00 +03:00
|
|
|
// If we are not already aware of this node, it means that we
|
|
|
|
// don't know about any channel using this node. To avoid a DoS
|
|
|
|
// attack by node announcements, we will ignore such nodes. If
|
|
|
|
// we do know about this node, check that this update brings
|
|
|
|
// info newer than what we already have.
|
2017-03-19 21:40:25 +03:00
|
|
|
lastUpdate, exists, err := r.cfg.Graph.HasLightningNode(msg.PubKey)
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
if err != nil {
|
2017-03-19 21:40:25 +03:00
|
|
|
return errors.Errorf("unable to query for the "+
|
|
|
|
"existence of node: %v", err)
|
2017-07-14 22:32:00 +03:00
|
|
|
}
|
|
|
|
if !exists {
|
|
|
|
return newErrf(ErrIgnored, "Ignoring node announcement"+
|
|
|
|
" for node not found in channel graph (%x)",
|
|
|
|
msg.PubKey.SerializeCompressed())
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
}
|
|
|
|
|
2017-07-14 22:32:00 +03:00
|
|
|
// If we've reached this point then we're aware of the vertex
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
// being advertised. So we now check if the new message has a
|
|
|
|
// new time stamp, if not then we won't accept the new data as
|
|
|
|
// it would override newer data.
|
2017-03-19 21:40:25 +03:00
|
|
|
if exists && lastUpdate.After(msg.LastUpdate) ||
|
|
|
|
lastUpdate.Equal(msg.LastUpdate) {
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
|
2017-04-12 07:19:37 +03:00
|
|
|
return newErrf(ErrOutdated, "Ignoring outdated "+
|
2017-03-19 21:40:25 +03:00
|
|
|
"announcement for %x", msg.PubKey.SerializeCompressed())
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
}
|
|
|
|
|
2017-03-19 21:40:25 +03:00
|
|
|
if err := r.cfg.Graph.AddLightningNode(msg); err != nil {
|
2017-04-01 15:33:17 +03:00
|
|
|
return errors.Errorf("unable to add node %v to the "+
|
2017-03-19 21:40:25 +03:00
|
|
|
"graph: %v", msg.PubKey.SerializeCompressed(), err)
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
log.Infof("Updated vertex data for node=%x",
|
2017-03-19 21:40:25 +03:00
|
|
|
msg.PubKey.SerializeCompressed())
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
|
2017-03-19 21:40:25 +03:00
|
|
|
case *channeldb.ChannelEdgeInfo:
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
// Prior to processing the announcement we first check if we
|
|
|
|
// already know of this channel, if so, then we can exit early.
|
2017-03-19 21:40:25 +03:00
|
|
|
_, _, exists, err := r.cfg.Graph.HasChannelEdge(msg.ChannelID)
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
if err != nil && err != channeldb.ErrGraphNoEdgesFound {
|
2017-03-19 21:40:25 +03:00
|
|
|
return errors.Errorf("unable to check for edge "+
|
|
|
|
"existence: %v", err)
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
} else if exists {
|
2017-04-12 07:19:37 +03:00
|
|
|
return newErrf(ErrIgnored, "Ignoring msg for known "+
|
2017-03-19 21:40:25 +03:00
|
|
|
"chan_id=%v", msg.ChannelID)
|
2017-02-03 04:44:13 +03:00
|
|
|
}
|
2017-02-02 05:29:46 +03:00
|
|
|
|
2017-07-14 22:32:00 +03:00
|
|
|
// Query the database for the existence of the two nodes in this
|
|
|
|
// channel. If not found, add a partial node to the database,
|
|
|
|
// containing only the node keys.
|
2017-05-15 05:27:14 +03:00
|
|
|
_, exists, _ = r.cfg.Graph.HasLightningNode(msg.NodeKey1)
|
|
|
|
if !exists {
|
2017-07-14 22:32:00 +03:00
|
|
|
node1 := &channeldb.LightningNode{
|
|
|
|
PubKey: msg.NodeKey1,
|
|
|
|
HaveNodeAnnouncement: false,
|
|
|
|
}
|
|
|
|
err := r.cfg.Graph.AddLightningNode(node1)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Errorf("unable to add node %v to"+
|
|
|
|
" the graph: %v",
|
|
|
|
node1.PubKey.SerializeCompressed(), err)
|
|
|
|
}
|
2017-05-15 05:27:14 +03:00
|
|
|
}
|
|
|
|
_, exists, _ = r.cfg.Graph.HasLightningNode(msg.NodeKey2)
|
|
|
|
if !exists {
|
2017-07-14 22:32:00 +03:00
|
|
|
node2 := &channeldb.LightningNode{
|
|
|
|
PubKey: msg.NodeKey2,
|
|
|
|
HaveNodeAnnouncement: false,
|
|
|
|
}
|
|
|
|
err := r.cfg.Graph.AddLightningNode(node2)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Errorf("unable to add node %v to"+
|
|
|
|
" the graph: %v",
|
|
|
|
node2.PubKey.SerializeCompressed(), err)
|
|
|
|
}
|
2017-05-15 05:27:14 +03:00
|
|
|
}
|
|
|
|
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
// Before we can add the channel to the channel graph, we need
|
|
|
|
// to obtain the full funding outpoint that's encoded within
|
|
|
|
// the channel ID.
|
2017-03-27 18:22:37 +03:00
|
|
|
channelID := lnwire.NewShortChanIDFromInt(msg.ChannelID)
|
2017-03-19 21:40:25 +03:00
|
|
|
fundingPoint, err := r.fetchChanPoint(&channelID)
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
if err != nil {
|
2017-03-19 21:40:25 +03:00
|
|
|
return errors.Errorf("unable to fetch chan point for "+
|
|
|
|
"chan_id=%v: %v", msg.ChannelID, err)
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Now that we have the funding outpoint of the channel, ensure
|
|
|
|
// that it hasn't yet been spent. If so, then this channel has
|
|
|
|
// been closed so we'll ignore it.
|
2017-05-11 03:22:26 +03:00
|
|
|
chanUtxo, err := r.cfg.Chain.GetUtxo(fundingPoint,
|
|
|
|
channelID.BlockHeight)
|
2017-03-09 01:27:46 +03:00
|
|
|
if err != nil {
|
2017-03-19 21:40:25 +03:00
|
|
|
return errors.Errorf("unable to fetch utxo for "+
|
2017-05-16 03:50:56 +03:00
|
|
|
"chan_id=%v, chan_point=%v: %v", msg.ChannelID,
|
|
|
|
fundingPoint, err)
|
2017-03-30 04:01:28 +03:00
|
|
|
}
|
|
|
|
|
2017-05-15 05:27:14 +03:00
|
|
|
// Recreate witness output to be sure that declared in channel
|
|
|
|
// edge bitcoin keys and channel value corresponds to the
|
|
|
|
// reality.
|
2017-03-30 04:01:28 +03:00
|
|
|
_, witnessOutput, err := lnwallet.GenFundingPkScript(
|
|
|
|
msg.BitcoinKey1.SerializeCompressed(),
|
|
|
|
msg.BitcoinKey2.SerializeCompressed(),
|
|
|
|
chanUtxo.Value,
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Errorf("unable to create funding pk "+
|
|
|
|
"script: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// By checking the equality of witness pkscripts we checks that
|
|
|
|
// funding witness script is multisignature lock which contains
|
|
|
|
// both local and remote public keys which was declared in
|
|
|
|
// channel edge and also that the announced channel value is
|
|
|
|
// right.
|
|
|
|
if !bytes.Equal(witnessOutput.PkScript, chanUtxo.PkScript) {
|
2017-05-16 03:50:56 +03:00
|
|
|
return errors.Errorf("pkScript mismatch: expected %x, "+
|
|
|
|
"got %x", witnessOutput.PkScript, chanUtxo.PkScript)
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
}
|
|
|
|
|
2017-03-19 21:40:25 +03:00
|
|
|
// TODO(roasbeef): this is a hack, needs to be removed
|
|
|
|
// after commitment fees are dynamic.
|
2017-05-01 21:45:02 +03:00
|
|
|
msg.Capacity = btcutil.Amount(chanUtxo.Value)
|
2017-03-19 21:40:25 +03:00
|
|
|
msg.ChannelPoint = *fundingPoint
|
|
|
|
if err := r.cfg.Graph.AddChannelEdge(msg); err != nil {
|
|
|
|
return errors.Errorf("unable to add edge: %v", err)
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
}
|
|
|
|
|
2017-03-21 07:28:39 +03:00
|
|
|
invalidateCache = true
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
log.Infof("New channel discovered! Link "+
|
2017-04-14 21:48:04 +03:00
|
|
|
"connects %x and %x with ChannelPoint(%v): "+
|
|
|
|
"chan_id=%v, capacity=%v",
|
2017-03-19 21:40:25 +03:00
|
|
|
msg.NodeKey1.SerializeCompressed(),
|
|
|
|
msg.NodeKey2.SerializeCompressed(),
|
2017-04-14 21:48:04 +03:00
|
|
|
fundingPoint, msg.ChannelID, msg.Capacity)
|
2017-03-19 21:40:25 +03:00
|
|
|
|
2017-05-11 03:22:26 +03:00
|
|
|
// As a new edge has been added to the channel graph, we'll
|
|
|
|
// update the current UTXO filter within our active
|
|
|
|
// FilteredChainView so we are notified if/when this channel is
|
|
|
|
// closed.
|
|
|
|
filterUpdate := []wire.OutPoint{*fundingPoint}
|
|
|
|
err = r.cfg.ChainView.UpdateFilter(filterUpdate, r.bestHeight)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Errorf("unable to update chain "+
|
|
|
|
"view: %v", err)
|
|
|
|
}
|
|
|
|
|
2017-03-19 21:40:25 +03:00
|
|
|
case *channeldb.ChannelEdgePolicy:
|
2017-03-27 18:22:37 +03:00
|
|
|
channelID := lnwire.NewShortChanIDFromInt(msg.ChannelID)
|
2017-08-22 09:58:38 +03:00
|
|
|
edge1Timestamp, edge2Timestamp, exists, err := r.cfg.Graph.HasChannelEdge(
|
|
|
|
msg.ChannelID,
|
|
|
|
)
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
if err != nil && err != channeldb.ErrGraphNoEdgesFound {
|
2017-03-19 21:40:25 +03:00
|
|
|
return errors.Errorf("unable to check for edge "+
|
|
|
|
"existence: %v", err)
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
|
2017-02-03 04:44:13 +03:00
|
|
|
}
|
|
|
|
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
// As edges are directional edge node has a unique policy for
|
2016-12-31 03:41:59 +03:00
|
|
|
// the direction of the edge they control. Therefore we first
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
// check if we already have the most up to date information for
|
|
|
|
// that edge. If so, then we can exit early.
|
|
|
|
switch msg.Flags {
|
|
|
|
|
2017-03-09 01:27:46 +03:00
|
|
|
// A flag set of 0 indicates this is an announcement for the
|
|
|
|
// "first" node in the channel.
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
case 0:
|
2017-03-19 21:40:25 +03:00
|
|
|
if edge1Timestamp.After(msg.LastUpdate) ||
|
|
|
|
edge1Timestamp.Equal(msg.LastUpdate) {
|
2017-10-25 04:22:58 +03:00
|
|
|
return newErrf(ErrIgnored, "Ignoring update "+
|
2017-03-19 21:40:25 +03:00
|
|
|
"(flags=%v) for known chan_id=%v", msg.Flags,
|
|
|
|
msg.ChannelID)
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-03-09 01:27:46 +03:00
|
|
|
// Similarly, a flag set of 1 indicates this is an announcement
|
|
|
|
// for the "second" node in the channel.
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
case 1:
|
2017-03-19 21:40:25 +03:00
|
|
|
if edge2Timestamp.After(msg.LastUpdate) ||
|
|
|
|
edge2Timestamp.Equal(msg.LastUpdate) {
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
|
2017-10-25 04:22:58 +03:00
|
|
|
return newErrf(ErrIgnored, "Ignoring update "+
|
2017-03-19 21:40:25 +03:00
|
|
|
"(flags=%v) for known chan_id=%v", msg.Flags,
|
|
|
|
msg.ChannelID)
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-22 09:58:38 +03:00
|
|
|
if !exists {
|
|
|
|
// Before we can update the channel information, we'll
|
|
|
|
// ensure that the target channel is still open by
|
|
|
|
// querying the utxo-set for its existence.
|
|
|
|
chanPoint, err := r.fetchChanPoint(&channelID)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Errorf("unable to fetch chan "+
|
|
|
|
"point for chan_id=%v: %v",
|
|
|
|
msg.ChannelID, err)
|
|
|
|
}
|
|
|
|
_, err = r.cfg.Chain.GetUtxo(
|
|
|
|
chanPoint, channelID.BlockHeight,
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Errorf("unable to fetch utxo for "+
|
|
|
|
"chan_id=%v: %v", msg.ChannelID, err)
|
|
|
|
}
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
}
|
|
|
|
|
2017-05-11 03:22:26 +03:00
|
|
|
// Now that we know this isn't a stale update, we'll apply the
|
|
|
|
// new edge policy to the proper directional edge within the
|
|
|
|
// channel graph.
|
2017-03-19 21:40:25 +03:00
|
|
|
if err = r.cfg.Graph.UpdateEdgePolicy(msg); err != nil {
|
|
|
|
err := errors.Errorf("unable to add channel: %v", err)
|
|
|
|
log.Error(err)
|
|
|
|
return err
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
}
|
|
|
|
|
2017-03-21 07:28:39 +03:00
|
|
|
invalidateCache = true
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
log.Infof("New channel update applied: %v",
|
2017-03-19 21:40:25 +03:00
|
|
|
spew.Sdump(msg))
|
|
|
|
|
|
|
|
default:
|
|
|
|
return errors.Errorf("wrong routing update message type")
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
}
|
|
|
|
|
2017-03-21 07:28:39 +03:00
|
|
|
// If we've received a channel update, then invalidate the route cache
|
|
|
|
// as channels within the graph have closed, which may affect our
|
|
|
|
// choice of the KSP's for a particular routeTuple.
|
|
|
|
if invalidateCache {
|
|
|
|
r.routeCacheMtx.Lock()
|
|
|
|
r.routeCache = make(map[routeTuple][]*Route)
|
|
|
|
r.routeCacheMtx.Unlock()
|
|
|
|
}
|
|
|
|
|
2017-03-19 21:40:25 +03:00
|
|
|
return nil
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// fetchChanPoint retrieves the original outpoint which is encoded within the
|
|
|
|
// channelID.
|
2017-05-11 03:22:26 +03:00
|
|
|
//
|
2017-10-11 05:48:44 +03:00
|
|
|
// TODO(roasbeef): replace with call to GetBlockTransaction? (would allow to
|
2017-05-11 03:22:26 +03:00
|
|
|
// later use getblocktxn)
|
2017-03-27 18:22:37 +03:00
|
|
|
func (r *ChannelRouter) fetchChanPoint(chanID *lnwire.ShortChannelID) (*wire.OutPoint, error) {
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
// First fetch the block hash by the block number encoded, then use
|
|
|
|
// that hash to fetch the block itself.
|
|
|
|
blockNum := int64(chanID.BlockHeight)
|
|
|
|
blockHash, err := r.cfg.Chain.GetBlockHash(blockNum)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
fundingBlock, err := r.cfg.Chain.GetBlock(blockHash)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2017-02-07 01:54:50 +03:00
|
|
|
// As a sanity check, ensure that the advertised transaction index is
|
|
|
|
// within the bounds of the total number of transactions within a
|
|
|
|
// block.
|
|
|
|
numTxns := uint32(len(fundingBlock.Transactions))
|
|
|
|
if chanID.TxIndex > numTxns-1 {
|
|
|
|
return nil, fmt.Errorf("tx_index=#%v is out of range "+
|
|
|
|
"(max_index=%v), network_chan_id=%v\n", chanID.TxIndex,
|
|
|
|
numTxns-1, spew.Sdump(chanID))
|
|
|
|
}
|
|
|
|
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
// Finally once we have the block itself, we seek to the targeted
|
|
|
|
// transaction index to obtain the funding output and txid.
|
|
|
|
fundingTx := fundingBlock.Transactions[chanID.TxIndex]
|
|
|
|
return &wire.OutPoint{
|
2017-01-06 00:56:27 +03:00
|
|
|
Hash: fundingTx.TxHash(),
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
Index: uint32(chanID.TxPosition),
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2017-03-19 21:40:25 +03:00
|
|
|
// routingMsg couples a routing related routing topology update to the
|
|
|
|
// error channel.
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
type routingMsg struct {
|
2017-03-19 21:40:25 +03:00
|
|
|
msg interface{}
|
|
|
|
err chan error
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
}
|
|
|
|
|
2017-10-11 05:45:38 +03:00
|
|
|
// pruneNodeFromRoutes accepts set of routes, and returns a new set of routes
|
|
|
|
// with the target node filtered out.
|
|
|
|
func pruneNodeFromRoutes(routes []*Route, skipNode vertex) []*Route {
|
|
|
|
|
|
|
|
// TODO(roasbeef): pass in slice index?
|
|
|
|
|
|
|
|
prunedRoutes := make([]*Route, 0, len(routes))
|
|
|
|
for _, route := range routes {
|
|
|
|
if route.containsNode(skipNode) {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
prunedRoutes = append(prunedRoutes, route)
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Tracef("Filtered out %v routes with node %x",
|
|
|
|
len(routes)-len(prunedRoutes), skipNode[:])
|
|
|
|
|
|
|
|
return prunedRoutes
|
|
|
|
}
|
|
|
|
|
|
|
|
// pruneChannelFromRoutes accepts a set of routes, and returns a new set of
|
|
|
|
// routes with the target channel filtered out.
|
|
|
|
func pruneChannelFromRoutes(routes []*Route, skipChan uint64) []*Route {
|
|
|
|
|
|
|
|
prunedRoutes := make([]*Route, 0, len(routes))
|
|
|
|
for _, route := range routes {
|
|
|
|
if route.containsChannel(skipChan) {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
prunedRoutes = append(prunedRoutes, route)
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Tracef("Filtered out %v routes with channel %v",
|
|
|
|
len(routes)-len(prunedRoutes), skipChan)
|
|
|
|
|
|
|
|
return prunedRoutes
|
|
|
|
}
|
|
|
|
|
2017-03-21 04:31:33 +03:00
|
|
|
// FindRoutes attempts to query the ChannelRouter for the all available paths
|
|
|
|
// to a particular target destination which is able to send `amt` after
|
|
|
|
// factoring in channel capacities and cumulative fees along each route route.
|
|
|
|
// To find all eligible paths, we use a modified version of Yen's algorithm
|
|
|
|
// which itself uses a modified version of Dijkstra's algorithm within its
|
|
|
|
// inner loop. Once we have a set of candidate routes, we calculate the
|
|
|
|
// 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.
|
2017-08-22 09:43:20 +03:00
|
|
|
func (r *ChannelRouter) FindRoutes(target *btcec.PublicKey,
|
2017-10-19 07:59:06 +03:00
|
|
|
amt lnwire.MilliSatoshi, finalExpiry ...uint16) ([]*Route, error) {
|
|
|
|
|
|
|
|
var finalCLTVDelta uint16
|
|
|
|
if len(finalExpiry) == 0 {
|
|
|
|
finalCLTVDelta = DefaultFinalCLTVDelta
|
|
|
|
} else {
|
|
|
|
finalCLTVDelta = finalExpiry[0]
|
|
|
|
}
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
|
routing: modify SendPayment loop to be lazy, iterative, and use missionControl
In this commit we modify the SendPayment loop to optimize for
time-to-first-payment-success-or-failure. The prior logic would first
attempt to find at least 100 routes to the destination, then
iteratively prune them away as errors were encountered. In this commit,
we modify this approach to instead take a lazy approach: we first find
the current “best” path, attempt to send to that, and if an error
occurs we prune a section of the graph by reporting to missionControl,
then continue.
With this new approach, if the first known path has sufficient
capacity, and is available, then the payment speed is greatly improved
from the PoV of users. Additionally, we avoid the excessive computation
of crawling most of the graph in the k-shortest paths loop. With the
decay on missionControl, all routes will now feed information into the
central knowledge hung, allowing all payments to iteratively find out
the inactive portions of the payment graph.
2017-10-17 05:05:39 +03:00
|
|
|
// TODO(roasbeef): make num routes a param
|
|
|
|
|
2017-08-22 09:43:20 +03:00
|
|
|
dest := target.SerializeCompressed()
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
log.Debugf("Searching for path to %x, sending %v", dest, amt)
|
|
|
|
|
2017-10-03 07:58:34 +03:00
|
|
|
// Before attempting to perform a series of graph traversals to find
|
|
|
|
// the k-shortest paths to the destination, we'll first consult our
|
|
|
|
// path cache
|
|
|
|
rt := newRouteTuple(amt, dest)
|
|
|
|
r.routeCacheMtx.RLock()
|
|
|
|
routes, ok := r.routeCache[rt]
|
|
|
|
r.routeCacheMtx.RUnlock()
|
|
|
|
|
|
|
|
// If we already have a cached route, then we'll return it directly as
|
|
|
|
// there's no need to repeat the computation.
|
|
|
|
if ok {
|
|
|
|
return routes, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we don't have a set of routes cached, we'll query the graph for a
|
|
|
|
// set of potential routes to the destination node that can support our
|
|
|
|
// payment amount. If no such routes can be found then an error will be
|
|
|
|
// returned.
|
|
|
|
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
// We can short circuit the routing by opportunistically checking to
|
|
|
|
// see if the target vertex event exists in the current graph.
|
|
|
|
if _, exists, err := r.cfg.Graph.HasLightningNode(target); err != nil {
|
|
|
|
return nil, err
|
|
|
|
} else if !exists {
|
|
|
|
log.Debugf("Target %x is not in known graph", dest)
|
2017-03-19 21:40:25 +03:00
|
|
|
return nil, newErrf(ErrTargetNotInNetwork, "target not found")
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
}
|
|
|
|
|
2017-08-03 07:02:18 +03:00
|
|
|
// We'll also fetch the current block height so we can properly
|
|
|
|
// calculate the required HTLC time locks within the route.
|
|
|
|
_, currentHeight, err := r.cfg.Chain.GetBestBlock()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2017-10-11 07:39:54 +03:00
|
|
|
tx, err := r.cfg.Graph.Database().Begin(false)
|
|
|
|
if err != nil {
|
|
|
|
tx.Rollback()
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2017-03-21 04:25:54 +03:00
|
|
|
// Now that we know the destination is reachable within the graph,
|
|
|
|
// we'll execute our KSP algorithm to find the k-shortest paths from
|
|
|
|
// our source to the destination.
|
2017-10-23 03:29:55 +03:00
|
|
|
shortestPaths, err := findPaths(tx, r.cfg.Graph, r.selfNode, target,
|
|
|
|
amt)
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
if err != nil {
|
2017-10-11 07:39:54 +03:00
|
|
|
tx.Rollback()
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2017-10-11 07:39:54 +03:00
|
|
|
tx.Rollback()
|
|
|
|
|
2017-03-21 04:25:54 +03:00
|
|
|
// Now that we have a set of paths, we'll need to turn them into
|
|
|
|
// *routes* by computing the required time-lock and fee information for
|
|
|
|
// each path. During this process, some paths may be discarded if they
|
|
|
|
// aren't able to support the total satoshis flow once fees have been
|
|
|
|
// factored in.
|
2017-09-04 23:58:30 +03:00
|
|
|
validRoutes := make([]*Route, 0, len(shortestPaths))
|
2017-10-23 03:29:55 +03:00
|
|
|
sourceVertex := newVertex(r.selfNode.PubKey)
|
2017-03-21 04:25:54 +03:00
|
|
|
for _, path := range shortestPaths {
|
|
|
|
// Attempt to make the path into a route. We snip off the first
|
2017-03-21 22:17:38 +03:00
|
|
|
// hop in the path as it contains a "self-hop" that is inserted
|
2017-03-21 04:25:54 +03:00
|
|
|
// by our KSP algorithm.
|
2017-10-11 05:45:09 +03:00
|
|
|
route, err := newRoute(amt, sourceVertex, path[1:],
|
2017-10-19 07:59:06 +03:00
|
|
|
uint32(currentHeight), finalCLTVDelta)
|
2017-03-21 04:25:54 +03:00
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the path as enough total flow to support the computed
|
|
|
|
// route, then we'll add it to our set of valid routes.
|
|
|
|
validRoutes = append(validRoutes, route)
|
2017-03-20 01:15:24 +03:00
|
|
|
}
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
|
2017-03-21 04:31:33 +03:00
|
|
|
// If all our perspective routes were eliminating during the transition
|
|
|
|
// from path to route, then we'll return an error to the caller
|
|
|
|
if len(validRoutes) == 0 {
|
2017-03-19 21:40:25 +03:00
|
|
|
return nil, newErr(ErrNoPathFound, "unable to find a path to "+
|
|
|
|
"destination")
|
2017-03-21 04:31:33 +03:00
|
|
|
}
|
|
|
|
|
2017-03-21 04:25:54 +03:00
|
|
|
// Finally, we'll sort the set of validate routes to optimize for
|
2017-09-07 03:29:07 +03:00
|
|
|
// lowest total fees, using the required time-lock within the
|
|
|
|
// route as a tie-breaker.
|
2017-09-04 23:58:30 +03:00
|
|
|
sort.Slice(validRoutes, func(i, j int) bool {
|
|
|
|
// To make this decision we first check if the total fees
|
2017-09-07 03:29:07 +03:00
|
|
|
// required for both routes are equal. If so, then we'll let
|
|
|
|
// the total time lock be the tie breaker. Otherwise, we'll
|
|
|
|
// put the route with the lowest total fees first.
|
2017-09-04 23:58:30 +03:00
|
|
|
if validRoutes[i].TotalFees == validRoutes[j].TotalFees {
|
|
|
|
timeLockI := validRoutes[i].TotalTimeLock
|
|
|
|
timeLockJ := validRoutes[j].TotalTimeLock
|
|
|
|
return timeLockI < timeLockJ
|
|
|
|
}
|
|
|
|
|
|
|
|
return validRoutes[i].TotalFees < validRoutes[j].TotalFees
|
|
|
|
})
|
2017-03-21 04:25:54 +03:00
|
|
|
|
2017-10-11 07:39:54 +03:00
|
|
|
go log.Tracef("Obtained %v paths sending %v to %x: %v", len(validRoutes),
|
2017-03-21 04:25:54 +03:00
|
|
|
amt, dest, newLogClosure(func() string {
|
|
|
|
return spew.Sdump(validRoutes)
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
}),
|
|
|
|
)
|
|
|
|
|
2017-10-03 07:58:34 +03:00
|
|
|
// Populate the cache with this set of fresh routes so we can
|
|
|
|
// reuse them in the future.
|
|
|
|
r.routeCacheMtx.Lock()
|
|
|
|
r.routeCache[rt] = validRoutes
|
|
|
|
r.routeCacheMtx.Unlock()
|
|
|
|
|
2017-03-21 04:25:54 +03:00
|
|
|
return validRoutes, nil
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
}
|
|
|
|
|
2017-02-02 05:29:46 +03:00
|
|
|
// generateSphinxPacket generates then encodes a sphinx packet which encodes
|
|
|
|
// the onion route specified by the passed layer 3 route. The blob returned
|
|
|
|
// from this function can immediately be included within an HTLC add packet to
|
|
|
|
// be sent to the first hop within the route.
|
2017-06-29 16:40:45 +03:00
|
|
|
func generateSphinxPacket(route *Route, paymentHash []byte) ([]byte,
|
|
|
|
*sphinx.Circuit, error) {
|
2017-02-02 05:29:46 +03:00
|
|
|
// First obtain all the public keys along the route which are contained
|
|
|
|
// in each hop.
|
|
|
|
nodes := make([]*btcec.PublicKey, len(route.Hops))
|
|
|
|
for i, hop := range route.Hops {
|
|
|
|
// We create a new instance of the public key to avoid possibly
|
|
|
|
// mutating the curve parameters, which are unset in a higher
|
|
|
|
// level in order to avoid spamming the logs.
|
|
|
|
pub := btcec.PublicKey{
|
2017-02-10 02:28:32 +03:00
|
|
|
Curve: btcec.S256(),
|
|
|
|
X: hop.Channel.Node.PubKey.X,
|
|
|
|
Y: hop.Channel.Node.PubKey.Y,
|
2017-02-02 05:29:46 +03:00
|
|
|
}
|
|
|
|
nodes[i] = &pub
|
|
|
|
}
|
|
|
|
|
|
|
|
// Next we generate the per-hop payload which gives each node within
|
|
|
|
// the route the necessary information (fees, CLTV value, etc) to
|
|
|
|
// properly forward the payment.
|
2017-06-16 23:42:55 +03:00
|
|
|
hopPayloads := route.ToHopPayloads()
|
|
|
|
|
|
|
|
log.Tracef("Constructed per-hop payloads for payment_hash=%x: %v",
|
|
|
|
paymentHash[:], spew.Sdump(hopPayloads))
|
2017-02-02 05:29:46 +03:00
|
|
|
|
|
|
|
sessionKey, err := btcec.NewPrivateKey(btcec.S256())
|
|
|
|
if err != nil {
|
2017-06-29 16:40:45 +03:00
|
|
|
return nil, nil, err
|
2017-02-02 05:29:46 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Next generate the onion routing packet which allows us to perform
|
|
|
|
// privacy preserving source routing across the network.
|
|
|
|
sphinxPacket, err := sphinx.NewOnionPacket(nodes, sessionKey,
|
|
|
|
hopPayloads, paymentHash)
|
|
|
|
if err != nil {
|
2017-06-29 16:40:45 +03:00
|
|
|
return nil, nil, err
|
2017-02-02 05:29:46 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Finally, encode Sphinx packet using it's wire representation to be
|
|
|
|
// included within the HTLC add packet.
|
|
|
|
var onionBlob bytes.Buffer
|
|
|
|
if err := sphinxPacket.Encode(&onionBlob); err != nil {
|
2017-06-29 16:40:45 +03:00
|
|
|
return nil, nil, err
|
2017-02-02 05:29:46 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
log.Tracef("Generated sphinx packet: %v",
|
|
|
|
newLogClosure(func() string {
|
|
|
|
// We unset the internal curve here in order to keep
|
|
|
|
// the logs from getting noisy.
|
2017-06-16 23:42:55 +03:00
|
|
|
sphinxPacket.EphemeralKey.Curve = nil
|
2017-02-02 05:29:46 +03:00
|
|
|
return spew.Sdump(sphinxPacket)
|
|
|
|
}),
|
|
|
|
)
|
|
|
|
|
2017-06-29 16:40:45 +03:00
|
|
|
return onionBlob.Bytes(), &sphinx.Circuit{
|
|
|
|
SessionKey: sessionKey,
|
|
|
|
PaymentPath: nodes,
|
|
|
|
}, nil
|
2017-02-02 05:29:46 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// LightningPayment describes a payment to be sent through the network to the
|
|
|
|
// final destination.
|
|
|
|
type LightningPayment struct {
|
|
|
|
// Target is the node in which the payment should be routed towards.
|
|
|
|
Target *btcec.PublicKey
|
|
|
|
|
2017-03-09 01:27:46 +03:00
|
|
|
// Amount is the value of the payment to send through the network in
|
2017-08-22 09:43:20 +03:00
|
|
|
// milli-satoshis.
|
|
|
|
Amount lnwire.MilliSatoshi
|
2017-02-02 05:29:46 +03:00
|
|
|
|
|
|
|
// PaymentHash is the r-hash value to use within the HTLC extended to
|
|
|
|
// the first hop.
|
|
|
|
PaymentHash [32]byte
|
|
|
|
|
2017-10-19 08:00:03 +03:00
|
|
|
// FinalCLTVDelta is the CTLV expiry delta to use for the _final_ hop
|
|
|
|
// in the route. This means that the final hop will have a CLTV delta
|
|
|
|
// of at least: currentHeight + FinalCLTVDelta. If this value is
|
|
|
|
// unspcified, then a default value of DefaultFinalCLTVDelta will be
|
|
|
|
// used.
|
|
|
|
FinalCLTVDelta *uint16
|
|
|
|
|
2017-03-09 01:27:46 +03:00
|
|
|
// TODO(roasbeef): add e2e message?
|
2017-02-02 05:29:46 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// SendPayment attempts to send a payment as described within the passed
|
|
|
|
// LightningPayment. This function is blocking and will return either: when the
|
|
|
|
// payment is successful, or all candidates routes have been attempted and
|
|
|
|
// resulted in a failed payment. If the payment succeeds, then a non-nil Route
|
|
|
|
// will be returned which describes the path the successful payment traversed
|
2017-02-21 10:57:43 +03:00
|
|
|
// within the network to reach the destination. Additionally, the payment
|
|
|
|
// preimage will also be returned.
|
|
|
|
func (r *ChannelRouter) SendPayment(payment *LightningPayment) ([32]byte, *Route, error) {
|
2017-03-21 04:58:21 +03:00
|
|
|
log.Tracef("Dispatching route for lightning payment: %v",
|
|
|
|
newLogClosure(func() string {
|
2017-03-21 07:28:39 +03:00
|
|
|
payment.Target.Curve = nil
|
2017-03-21 04:58:21 +03:00
|
|
|
return spew.Sdump(payment)
|
|
|
|
}),
|
|
|
|
)
|
|
|
|
|
2017-02-21 10:57:43 +03:00
|
|
|
var (
|
2017-03-21 04:58:21 +03:00
|
|
|
preImage [32]byte
|
2017-10-03 08:03:18 +03:00
|
|
|
sendError error
|
2017-02-21 10:57:43 +03:00
|
|
|
)
|
|
|
|
|
routing: modify SendPayment loop to be lazy, iterative, and use missionControl
In this commit we modify the SendPayment loop to optimize for
time-to-first-payment-success-or-failure. The prior logic would first
attempt to find at least 100 routes to the destination, then
iteratively prune them away as errors were encountered. In this commit,
we modify this approach to instead take a lazy approach: we first find
the current “best” path, attempt to send to that, and if an error
occurs we prune a section of the graph by reporting to missionControl,
then continue.
With this new approach, if the first known path has sufficient
capacity, and is available, then the payment speed is greatly improved
from the PoV of users. Additionally, we avoid the excessive computation
of crawling most of the graph in the k-shortest paths loop. With the
decay on missionControl, all routes will now feed information into the
central knowledge hung, allowing all payments to iteratively find out
the inactive portions of the payment graph.
2017-10-17 05:05:39 +03:00
|
|
|
// We'll also fetch the current block height so we can properly
|
|
|
|
// calculate the required HTLC time locks within the route.
|
|
|
|
_, currentHeight, err := r.cfg.Chain.GetBestBlock()
|
2017-10-03 07:58:34 +03:00
|
|
|
if err != nil {
|
|
|
|
return preImage, nil, err
|
2017-02-02 05:29:46 +03:00
|
|
|
}
|
|
|
|
|
2017-10-19 08:00:03 +03:00
|
|
|
var finalCLTVDelta uint16
|
|
|
|
if payment.FinalCLTVDelta == nil {
|
|
|
|
finalCLTVDelta = DefaultFinalCLTVDelta
|
|
|
|
} else {
|
|
|
|
finalCLTVDelta = *payment.FinalCLTVDelta
|
|
|
|
}
|
|
|
|
|
routing: modify SendPayment loop to be lazy, iterative, and use missionControl
In this commit we modify the SendPayment loop to optimize for
time-to-first-payment-success-or-failure. The prior logic would first
attempt to find at least 100 routes to the destination, then
iteratively prune them away as errors were encountered. In this commit,
we modify this approach to instead take a lazy approach: we first find
the current “best” path, attempt to send to that, and if an error
occurs we prune a section of the graph by reporting to missionControl,
then continue.
With this new approach, if the first known path has sufficient
capacity, and is available, then the payment speed is greatly improved
from the PoV of users. Additionally, we avoid the excessive computation
of crawling most of the graph in the k-shortest paths loop. With the
decay on missionControl, all routes will now feed information into the
central knowledge hung, allowing all payments to iteratively find out
the inactive portions of the payment graph.
2017-10-17 05:05:39 +03:00
|
|
|
// We'll continue until either our payment succeeds, or we encounter a
|
|
|
|
// critical error during path finding.
|
|
|
|
for {
|
2017-10-18 05:41:46 +03:00
|
|
|
// We'll kick things off by requesting a new route from mission
|
|
|
|
// control, which will incoroporate the current best known
|
|
|
|
// state of the channel graph and our past HTLC routing
|
|
|
|
// successes/failures.
|
|
|
|
route, err := r.missionControl.RequestRoute(payment,
|
2017-10-23 03:28:18 +03:00
|
|
|
uint32(currentHeight), finalCLTVDelta)
|
routing: modify SendPayment loop to be lazy, iterative, and use missionControl
In this commit we modify the SendPayment loop to optimize for
time-to-first-payment-success-or-failure. The prior logic would first
attempt to find at least 100 routes to the destination, then
iteratively prune them away as errors were encountered. In this commit,
we modify this approach to instead take a lazy approach: we first find
the current “best” path, attempt to send to that, and if an error
occurs we prune a section of the graph by reporting to missionControl,
then continue.
With this new approach, if the first known path has sufficient
capacity, and is available, then the payment speed is greatly improved
from the PoV of users. Additionally, we avoid the excessive computation
of crawling most of the graph in the k-shortest paths loop. With the
decay on missionControl, all routes will now feed information into the
central knowledge hung, allowing all payments to iteratively find out
the inactive portions of the payment graph.
2017-10-17 05:05:39 +03:00
|
|
|
if err != nil {
|
|
|
|
// If we're unable to successfully make a payment using
|
|
|
|
// any of the routes we've found, then return an error.
|
|
|
|
if sendError != nil {
|
|
|
|
return [32]byte{}, nil, fmt.Errorf("unable to "+
|
|
|
|
"route payment to destination: %v",
|
|
|
|
sendError)
|
|
|
|
}
|
|
|
|
|
|
|
|
return preImage, nil, err
|
|
|
|
}
|
|
|
|
|
2017-03-21 07:28:39 +03:00
|
|
|
log.Tracef("Attempting to send payment %x, using route: %v",
|
2017-03-21 04:58:21 +03:00
|
|
|
payment.PaymentHash, newLogClosure(func() string {
|
|
|
|
return spew.Sdump(route)
|
|
|
|
}),
|
|
|
|
)
|
|
|
|
|
|
|
|
// Generate the raw encoded sphinx packet to be included along
|
|
|
|
// with the htlcAdd message that we send directly to the
|
|
|
|
// switch.
|
2017-06-29 16:40:45 +03:00
|
|
|
onionBlob, circuit, err := generateSphinxPacket(route,
|
|
|
|
payment.PaymentHash[:])
|
2017-03-21 04:58:21 +03:00
|
|
|
if err != nil {
|
|
|
|
return preImage, nil, err
|
|
|
|
}
|
2017-02-02 05:29:46 +03:00
|
|
|
|
2017-03-21 04:58:21 +03:00
|
|
|
// Craft an HTLC packet to send to the layer 2 switch. The
|
|
|
|
// metadata within this packet will be used to route the
|
|
|
|
// payment through the network, starting with the first-hop.
|
|
|
|
htlcAdd := &lnwire.UpdateAddHTLC{
|
|
|
|
Amount: route.TotalAmount,
|
2017-06-16 23:35:06 +03:00
|
|
|
Expiry: route.TotalTimeLock,
|
2017-03-21 04:58:21 +03:00
|
|
|
PaymentHash: payment.PaymentHash,
|
|
|
|
}
|
2017-06-29 16:40:45 +03:00
|
|
|
copy(htlcAdd.OnionBlob[:], onionBlob)
|
2017-03-21 04:58:21 +03:00
|
|
|
|
|
|
|
// Attempt to send this payment through the network to complete
|
|
|
|
// the payment. If this attempt fails, then we'll continue on
|
|
|
|
// to the next available route.
|
|
|
|
firstHop := route.Hops[0].Channel.Node.PubKey
|
2017-06-29 16:40:45 +03:00
|
|
|
preImage, sendError = r.cfg.SendToSwitch(firstHop, htlcAdd,
|
|
|
|
circuit)
|
2017-03-21 04:58:21 +03:00
|
|
|
if sendError != nil {
|
2017-10-03 08:03:18 +03:00
|
|
|
// An error occurred when attempting to send the
|
|
|
|
// payment, depending on the error type, we'll either
|
|
|
|
// continue to send using alternative routes, or simply
|
|
|
|
// terminate this attempt.
|
2017-03-21 04:58:21 +03:00
|
|
|
log.Errorf("Attempt to send payment %x failed: %v",
|
2017-04-15 03:12:04 +03:00
|
|
|
payment.PaymentHash, sendError)
|
2017-09-08 13:39:24 +03:00
|
|
|
|
2017-10-11 05:48:44 +03:00
|
|
|
fErr, ok := sendError.(*htlcswitch.ForwardingError)
|
|
|
|
if !ok {
|
2017-10-11 08:16:22 +03:00
|
|
|
return preImage, nil, sendError
|
2017-10-11 05:48:44 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
errSource := fErr.ErrorSource
|
|
|
|
|
|
|
|
switch onionErr := fErr.FailureMessage.(type) {
|
2017-10-03 08:03:18 +03:00
|
|
|
// If the end destination didn't know they payment
|
|
|
|
// hash, then we'll terminate immediately.
|
2017-09-08 13:39:24 +03:00
|
|
|
case *lnwire.FailUnknownPaymentHash:
|
2017-10-03 08:03:18 +03:00
|
|
|
return preImage, nil, sendError
|
|
|
|
|
|
|
|
// If we sent the wrong amount to the destination, then
|
|
|
|
// we'll exit early.
|
2017-09-08 13:39:24 +03:00
|
|
|
case *lnwire.FailIncorrectPaymentAmount:
|
2017-10-03 08:03:18 +03:00
|
|
|
return preImage, nil, sendError
|
|
|
|
|
|
|
|
// If the time-lock that was extended to the final node
|
|
|
|
// was incorrect, then we can't proceed.
|
|
|
|
case *lnwire.FailFinalIncorrectCltvExpiry:
|
|
|
|
return preImage, nil, sendError
|
|
|
|
|
|
|
|
// If we crafted an invalid onion payload for the final
|
|
|
|
// node, then we'll exit early.
|
|
|
|
case *lnwire.FailFinalIncorrectHtlcAmount:
|
|
|
|
return preImage, nil, sendError
|
|
|
|
|
|
|
|
// Similarly, if the HTLC expiry that we extended to
|
|
|
|
// the final hop expires too soon, then will fail the
|
|
|
|
// payment.
|
|
|
|
//
|
|
|
|
// TODO(roasbeef): can happen to to race condition, try
|
|
|
|
// again with recent block height
|
2017-09-08 13:39:24 +03:00
|
|
|
case *lnwire.FailFinalExpiryTooSoon:
|
2017-10-03 08:03:18 +03:00
|
|
|
return preImage, nil, sendError
|
|
|
|
|
|
|
|
// If we erroneously attempted to cross a chain border,
|
|
|
|
// then we'll cancel the payment.
|
|
|
|
case *lnwire.FailInvalidRealm:
|
|
|
|
return preImage, nil, sendError
|
|
|
|
|
|
|
|
// If we get a notice that the expiry was too soon for
|
|
|
|
// an intermediate node, then we'll exit early as the
|
|
|
|
// expected block height as shifted from underneath us.
|
|
|
|
case *lnwire.FailExpiryTooSoon:
|
|
|
|
update := onionErr.Update
|
|
|
|
if err := r.applyChannelUpdate(&update); err != nil {
|
|
|
|
return preImage, nil, err
|
|
|
|
}
|
|
|
|
return preImage, nil, sendError
|
|
|
|
|
|
|
|
// If we hit an instance of onion payload corruption or
|
|
|
|
// an invalid version, then we'll exit early as this
|
|
|
|
// shouldn't happen in the typical case.
|
2017-09-08 13:39:24 +03:00
|
|
|
case *lnwire.FailInvalidOnionVersion:
|
2017-10-03 08:03:18 +03:00
|
|
|
return preImage, nil, sendError
|
2017-09-08 13:39:24 +03:00
|
|
|
case *lnwire.FailInvalidOnionHmac:
|
2017-10-03 08:03:18 +03:00
|
|
|
return preImage, nil, sendError
|
2017-09-08 13:39:24 +03:00
|
|
|
case *lnwire.FailInvalidOnionKey:
|
2017-10-03 08:03:18 +03:00
|
|
|
return preImage, nil, sendError
|
|
|
|
|
|
|
|
// If the onion error includes a channel update, and
|
|
|
|
// isn't necessarily fatal, then we'll apply the update
|
|
|
|
// an continue with the rest of the routes.
|
|
|
|
//
|
|
|
|
// TODO(roasbeef): should re-query for routes with new updates
|
2017-09-08 13:39:24 +03:00
|
|
|
case *lnwire.FailAmountBelowMinimum:
|
2017-10-03 08:03:18 +03:00
|
|
|
update := onionErr.Update
|
|
|
|
if err := r.applyChannelUpdate(&update); err != nil {
|
|
|
|
return preImage, nil, err
|
|
|
|
}
|
2017-10-17 04:58:26 +03:00
|
|
|
|
|
|
|
return preImage, nil, sendError
|
2017-09-08 13:39:24 +03:00
|
|
|
case *lnwire.FailFeeInsufficient:
|
2017-10-03 08:03:18 +03:00
|
|
|
update := onionErr.Update
|
|
|
|
if err := r.applyChannelUpdate(&update); err != nil {
|
|
|
|
return preImage, nil, err
|
|
|
|
}
|
2017-10-17 04:58:26 +03:00
|
|
|
|
|
|
|
return preImage, nil, sendError
|
2017-10-03 08:03:18 +03:00
|
|
|
case *lnwire.FailIncorrectCltvExpiry:
|
|
|
|
update := onionErr.Update
|
|
|
|
if err := r.applyChannelUpdate(&update); err != nil {
|
|
|
|
return preImage, nil, err
|
|
|
|
}
|
2017-10-17 04:58:26 +03:00
|
|
|
|
|
|
|
return preImage, nil, sendError
|
2017-09-08 13:39:24 +03:00
|
|
|
case *lnwire.FailChannelDisabled:
|
2017-10-03 08:03:18 +03:00
|
|
|
update := onionErr.Update
|
|
|
|
if err := r.applyChannelUpdate(&update); err != nil {
|
|
|
|
return preImage, nil, err
|
|
|
|
}
|
2017-10-17 04:58:26 +03:00
|
|
|
|
|
|
|
return preImage, nil, sendError
|
2017-10-03 08:03:18 +03:00
|
|
|
case *lnwire.FailTemporaryChannelFailure:
|
|
|
|
update := onionErr.Update
|
|
|
|
if err := r.applyChannelUpdate(update); err != nil {
|
|
|
|
return preImage, nil, err
|
|
|
|
}
|
2017-10-11 05:48:44 +03:00
|
|
|
|
|
|
|
// As this error indicates that the target
|
|
|
|
// channel was unable to carry this HTLC (for
|
|
|
|
// w/e reason), we'll query the index to find
|
|
|
|
// the _outgoign_ channel the source of the
|
|
|
|
// error was meant to pass the HTLC along to.
|
|
|
|
badChan, ok := route.nextHopChannel(errSource)
|
|
|
|
if !ok {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
routing: modify SendPayment loop to be lazy, iterative, and use missionControl
In this commit we modify the SendPayment loop to optimize for
time-to-first-payment-success-or-failure. The prior logic would first
attempt to find at least 100 routes to the destination, then
iteratively prune them away as errors were encountered. In this commit,
we modify this approach to instead take a lazy approach: we first find
the current “best” path, attempt to send to that, and if an error
occurs we prune a section of the graph by reporting to missionControl,
then continue.
With this new approach, if the first known path has sufficient
capacity, and is available, then the payment speed is greatly improved
from the PoV of users. Additionally, we avoid the excessive computation
of crawling most of the graph in the k-shortest paths loop. With the
decay on missionControl, all routes will now feed information into the
central knowledge hung, allowing all payments to iteratively find out
the inactive portions of the payment graph.
2017-10-17 05:05:39 +03:00
|
|
|
// If the channel was found, then we'll inform
|
|
|
|
// mission control of this failure so future
|
|
|
|
// attempts avoid this link temporarily.
|
|
|
|
r.missionControl.ReportChannelFailure(badChan)
|
|
|
|
continue
|
2017-10-03 08:03:18 +03:00
|
|
|
|
|
|
|
// If the send fail due to a node not having the
|
|
|
|
// required features, then we'll note this error and
|
routing: modify SendPayment loop to be lazy, iterative, and use missionControl
In this commit we modify the SendPayment loop to optimize for
time-to-first-payment-success-or-failure. The prior logic would first
attempt to find at least 100 routes to the destination, then
iteratively prune them away as errors were encountered. In this commit,
we modify this approach to instead take a lazy approach: we first find
the current “best” path, attempt to send to that, and if an error
occurs we prune a section of the graph by reporting to missionControl,
then continue.
With this new approach, if the first known path has sufficient
capacity, and is available, then the payment speed is greatly improved
from the PoV of users. Additionally, we avoid the excessive computation
of crawling most of the graph in the k-shortest paths loop. With the
decay on missionControl, all routes will now feed information into the
central knowledge hung, allowing all payments to iteratively find out
the inactive portions of the payment graph.
2017-10-17 05:05:39 +03:00
|
|
|
// continue.
|
|
|
|
//
|
2017-10-03 08:03:18 +03:00
|
|
|
// TODO(roasbeef): remove node from path
|
|
|
|
case *lnwire.FailRequiredNodeFeatureMissing:
|
|
|
|
continue
|
|
|
|
|
|
|
|
// If the send fail due to a node not having the
|
|
|
|
// required features, then we'll note this error and
|
routing: modify SendPayment loop to be lazy, iterative, and use missionControl
In this commit we modify the SendPayment loop to optimize for
time-to-first-payment-success-or-failure. The prior logic would first
attempt to find at least 100 routes to the destination, then
iteratively prune them away as errors were encountered. In this commit,
we modify this approach to instead take a lazy approach: we first find
the current “best” path, attempt to send to that, and if an error
occurs we prune a section of the graph by reporting to missionControl,
then continue.
With this new approach, if the first known path has sufficient
capacity, and is available, then the payment speed is greatly improved
from the PoV of users. Additionally, we avoid the excessive computation
of crawling most of the graph in the k-shortest paths loop. With the
decay on missionControl, all routes will now feed information into the
central knowledge hung, allowing all payments to iteratively find out
the inactive portions of the payment graph.
2017-10-17 05:05:39 +03:00
|
|
|
// continue.
|
2017-10-03 08:03:18 +03:00
|
|
|
//
|
|
|
|
// TODO(roasbeef): remove channel from path
|
|
|
|
case *lnwire.FailRequiredChannelFeatureMissing:
|
|
|
|
continue
|
|
|
|
|
|
|
|
// If the next hop in the route wasn't known or
|
2017-10-11 05:48:44 +03:00
|
|
|
// offline, we'll prune the _next_ hop from the set of
|
|
|
|
// routes and retry.
|
2017-10-03 08:03:18 +03:00
|
|
|
case *lnwire.FailUnknownNextPeer:
|
2017-10-11 05:48:44 +03:00
|
|
|
// This failure indicates that the node _after_
|
|
|
|
// the source of the error was not found. As a
|
|
|
|
// result, we'll locate the vertex for that
|
|
|
|
// node itself.
|
|
|
|
missingNode, ok := route.nextHopVertex(errSource)
|
|
|
|
if !ok {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
routing: modify SendPayment loop to be lazy, iterative, and use missionControl
In this commit we modify the SendPayment loop to optimize for
time-to-first-payment-success-or-failure. The prior logic would first
attempt to find at least 100 routes to the destination, then
iteratively prune them away as errors were encountered. In this commit,
we modify this approach to instead take a lazy approach: we first find
the current “best” path, attempt to send to that, and if an error
occurs we prune a section of the graph by reporting to missionControl,
then continue.
With this new approach, if the first known path has sufficient
capacity, and is available, then the payment speed is greatly improved
from the PoV of users. Additionally, we avoid the excessive computation
of crawling most of the graph in the k-shortest paths loop. With the
decay on missionControl, all routes will now feed information into the
central knowledge hung, allowing all payments to iteratively find out
the inactive portions of the payment graph.
2017-10-17 05:05:39 +03:00
|
|
|
// Once we've located the vertex, we'll report
|
|
|
|
// this failure to missionControl and restart
|
|
|
|
// path finding.
|
|
|
|
r.missionControl.ReportVertexFailure(missingNode)
|
|
|
|
continue
|
2017-10-03 08:03:18 +03:00
|
|
|
|
|
|
|
// If the node wasn't able to forward for which ever
|
|
|
|
// reason, then we'll note this and continue with the
|
|
|
|
// routes.
|
|
|
|
case *lnwire.FailTemporaryNodeFailure:
|
routing: modify SendPayment loop to be lazy, iterative, and use missionControl
In this commit we modify the SendPayment loop to optimize for
time-to-first-payment-success-or-failure. The prior logic would first
attempt to find at least 100 routes to the destination, then
iteratively prune them away as errors were encountered. In this commit,
we modify this approach to instead take a lazy approach: we first find
the current “best” path, attempt to send to that, and if an error
occurs we prune a section of the graph by reporting to missionControl,
then continue.
With this new approach, if the first known path has sufficient
capacity, and is available, then the payment speed is greatly improved
from the PoV of users. Additionally, we avoid the excessive computation
of crawling most of the graph in the k-shortest paths loop. With the
decay on missionControl, all routes will now feed information into the
central knowledge hung, allowing all payments to iteratively find out
the inactive portions of the payment graph.
2017-10-17 05:05:39 +03:00
|
|
|
missingNode, ok := route.nextHopVertex(errSource)
|
|
|
|
if !ok {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
r.missionControl.ReportVertexFailure(missingNode)
|
2017-10-03 08:03:18 +03:00
|
|
|
continue
|
|
|
|
|
|
|
|
// If we get a permanent channel or node failure, then
|
|
|
|
// we'll note this (exclude the vertex/edge), and
|
|
|
|
// continue with the rest of the routes.
|
|
|
|
case *lnwire.FailPermanentChannelFailure:
|
|
|
|
// TODO(roasbeef): remove channel from path
|
|
|
|
continue
|
|
|
|
case *lnwire.FailPermanentNodeFailure:
|
|
|
|
// TODO(rosabeef): remove node from path
|
|
|
|
continue
|
|
|
|
|
|
|
|
default:
|
|
|
|
return preImage, nil, sendError
|
2017-09-08 13:39:24 +03:00
|
|
|
}
|
2017-03-21 04:58:21 +03:00
|
|
|
}
|
2017-02-02 05:29:46 +03:00
|
|
|
|
2017-03-21 04:58:21 +03:00
|
|
|
return preImage, route, nil
|
2017-02-02 05:29:46 +03:00
|
|
|
}
|
2017-10-03 08:03:18 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// applyChannelUpdate applies a channel update directly to the database,
|
|
|
|
// skipping preliminary validation.
|
|
|
|
func (r *ChannelRouter) applyChannelUpdate(msg *lnwire.ChannelUpdate) error {
|
|
|
|
// If we get passed a nil channel update (as it's optional with some
|
|
|
|
// onion errors), then we'll exit early with a nil error.
|
|
|
|
if msg == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
err := r.UpdateEdge(&channeldb.ChannelEdgePolicy{
|
|
|
|
Signature: msg.Signature,
|
|
|
|
ChannelID: msg.ShortChannelID.ToUint64(),
|
|
|
|
LastUpdate: time.Unix(int64(msg.Timestamp), 0),
|
|
|
|
Flags: msg.Flags,
|
|
|
|
TimeLockDelta: msg.TimeLockDelta,
|
|
|
|
MinHTLC: msg.HtlcMinimumMsat,
|
|
|
|
FeeBaseMSat: lnwire.MilliSatoshi(msg.BaseFee),
|
|
|
|
FeeProportionalMillionths: lnwire.MilliSatoshi(msg.FeeRate),
|
|
|
|
})
|
2017-10-25 04:22:58 +03:00
|
|
|
if err != nil && !IsError(err, ErrIgnored) {
|
2017-10-03 08:03:18 +03:00
|
|
|
return fmt.Errorf("Unable to apply channel update: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
routing: rewrite package to conform to BOLT07 and factor in fees+timelocks
This commit overhauls the routing package significantly to simplify the
code, conform to the rest of the coding style within the package, and
observe the new authenticated gossiping scheme outlined in BOLT07.
As a major step towards a more realistic path finding algorithm, fees
are properly calculated and observed during path finding. If a path has
sufficient capacity _before_ fees are applied, but afterwards the
finalized route would exceed the capacity of a single link, the route
is marked as invalid.
Currently a naive weighting algorithm is used which only factors in the
time-lock delta at each hop, thereby optimizing for the lowest time
lock. Fee calculation also isn’t finalized since we aren’t yet using
milli-satoshi throughout the daemon. The final TODO item within the PR
is to properly perform a multi-path search and rank the results based
on a summation heuristic rather than just return the first (out of
many) route found.
On the server side, once nodes are initially connected to the daemon,
our routing table will be synced with the peer’s using a naive “just
send everything scheme” to hold us over until I spec out some a
efficient graph reconciliation protocol. Additionally, the routing
table is now pruned by the channel router itself once new blocks arrive
rather than depending on peers to tell us when a channel flaps or is
closed.
Finally, the validation of peer announcements aren’t yet fully
implemented as they’ll be implemented within the pending discovery
package that was blocking on the completion of this package. Most off
the routing message processing will be moved out of this package and
into the discovery package where full validation will be carried out.
2016-12-27 08:20:26 +03:00
|
|
|
}
|
2017-03-19 21:40:25 +03:00
|
|
|
|
2017-07-14 22:32:00 +03:00
|
|
|
// AddNode is used to add information about a node to the router database. If
|
|
|
|
// the node with this pubkey is not present in an existing channel, it will
|
|
|
|
// be ignored.
|
2017-04-01 15:33:17 +03:00
|
|
|
//
|
|
|
|
// NOTE: This method is part of the ChannelGraphSource interface.
|
2017-03-19 21:40:25 +03:00
|
|
|
func (r *ChannelRouter) AddNode(node *channeldb.LightningNode) error {
|
|
|
|
rMsg := &routingMsg{
|
|
|
|
msg: node,
|
|
|
|
err: make(chan error, 1),
|
|
|
|
}
|
|
|
|
|
|
|
|
select {
|
|
|
|
case r.networkUpdates <- rMsg:
|
2017-09-26 06:55:04 +03:00
|
|
|
select {
|
|
|
|
case err := <-rMsg.err:
|
|
|
|
return err
|
|
|
|
case <-r.quit:
|
|
|
|
return errors.New("router has been shut down")
|
|
|
|
}
|
2017-03-19 21:40:25 +03:00
|
|
|
case <-r.quit:
|
2017-09-26 06:55:04 +03:00
|
|
|
return errors.New("router has been shut down")
|
2017-03-19 21:40:25 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-01 15:33:17 +03:00
|
|
|
// AddEdge is used to add edge/channel to the topology of the router, after all
|
2017-10-11 05:48:44 +03:00
|
|
|
// information about channel will be gathered this edge/channel might be used
|
|
|
|
// in construction of payment path.
|
2017-04-01 15:33:17 +03:00
|
|
|
//
|
|
|
|
// NOTE: This method is part of the ChannelGraphSource interface.
|
2017-03-19 21:40:25 +03:00
|
|
|
func (r *ChannelRouter) AddEdge(edge *channeldb.ChannelEdgeInfo) error {
|
|
|
|
rMsg := &routingMsg{
|
|
|
|
msg: edge,
|
|
|
|
err: make(chan error, 1),
|
|
|
|
}
|
|
|
|
|
|
|
|
select {
|
|
|
|
case r.networkUpdates <- rMsg:
|
2017-09-26 06:55:04 +03:00
|
|
|
select {
|
|
|
|
case err := <-rMsg.err:
|
|
|
|
return err
|
|
|
|
case <-r.quit:
|
|
|
|
return errors.New("router has been shut down")
|
|
|
|
}
|
2017-03-19 21:40:25 +03:00
|
|
|
case <-r.quit:
|
2017-09-26 06:55:04 +03:00
|
|
|
return errors.New("router has been shut down")
|
2017-03-19 21:40:25 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-01 15:33:17 +03:00
|
|
|
// UpdateEdge is used to update edge information, without this message edge
|
|
|
|
// considered as not fully constructed.
|
|
|
|
//
|
|
|
|
// NOTE: This method is part of the ChannelGraphSource interface.
|
2017-03-19 21:40:25 +03:00
|
|
|
func (r *ChannelRouter) UpdateEdge(update *channeldb.ChannelEdgePolicy) error {
|
|
|
|
rMsg := &routingMsg{
|
|
|
|
msg: update,
|
|
|
|
err: make(chan error, 1),
|
|
|
|
}
|
|
|
|
|
|
|
|
select {
|
|
|
|
case r.networkUpdates <- rMsg:
|
2017-09-26 06:55:04 +03:00
|
|
|
select {
|
|
|
|
case err := <-rMsg.err:
|
|
|
|
return err
|
|
|
|
case <-r.quit:
|
|
|
|
return errors.New("router has been shut down")
|
|
|
|
}
|
2017-03-19 21:40:25 +03:00
|
|
|
case <-r.quit:
|
2017-09-26 06:55:04 +03:00
|
|
|
return errors.New("router has been shut down")
|
2017-03-19 21:40:25 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// CurrentBlockHeight returns the block height from POV of the router subsystem.
|
2017-04-01 15:33:17 +03:00
|
|
|
//
|
|
|
|
// NOTE: This method is part of the ChannelGraphSource interface.
|
2017-03-19 21:40:25 +03:00
|
|
|
func (r *ChannelRouter) CurrentBlockHeight() (uint32, error) {
|
|
|
|
_, height, err := r.cfg.Chain.GetBestBlock()
|
|
|
|
return uint32(height), err
|
|
|
|
}
|
|
|
|
|
2017-03-30 04:01:28 +03:00
|
|
|
// GetChannelByID return the channel by the channel id.
|
2017-04-01 15:33:17 +03:00
|
|
|
//
|
|
|
|
// NOTE: This method is part of the ChannelGraphSource interface.
|
2017-03-30 04:01:28 +03:00
|
|
|
func (r *ChannelRouter) GetChannelByID(chanID lnwire.ShortChannelID) (
|
|
|
|
*channeldb.ChannelEdgeInfo,
|
|
|
|
*channeldb.ChannelEdgePolicy,
|
|
|
|
*channeldb.ChannelEdgePolicy, error) {
|
2017-04-01 15:33:17 +03:00
|
|
|
|
2017-03-30 04:01:28 +03:00
|
|
|
return r.cfg.Graph.FetchChannelEdgesByID(chanID.ToUint64())
|
|
|
|
}
|
|
|
|
|
2017-03-19 21:40:25 +03:00
|
|
|
// ForEachNode is used to iterate over every node in router topology.
|
2017-04-01 15:33:17 +03:00
|
|
|
//
|
|
|
|
// NOTE: This method is part of the ChannelGraphSource interface.
|
2017-03-19 21:40:25 +03:00
|
|
|
func (r *ChannelRouter) ForEachNode(cb func(*channeldb.LightningNode) error) error {
|
2017-04-14 23:14:54 +03:00
|
|
|
return r.cfg.Graph.ForEachNode(nil, func(_ *bolt.Tx, n *channeldb.LightningNode) error {
|
|
|
|
return cb(n)
|
|
|
|
})
|
2017-03-19 21:40:25 +03:00
|
|
|
}
|
|
|
|
|
2017-04-01 15:33:17 +03:00
|
|
|
// ForAllOutgoingChannels is used to iterate over all outgiong channel owned by
|
|
|
|
// the router.
|
|
|
|
//
|
|
|
|
// NOTE: This method is part of the ChannelGraphSource interface.
|
2017-08-22 09:58:59 +03:00
|
|
|
func (r *ChannelRouter) ForAllOutgoingChannels(cb func(*channeldb.ChannelEdgeInfo,
|
|
|
|
*channeldb.ChannelEdgePolicy) error) error {
|
2017-04-01 15:33:17 +03:00
|
|
|
|
2017-10-23 03:29:55 +03:00
|
|
|
return r.selfNode.ForEachChannel(nil, func(_ *bolt.Tx, c *channeldb.ChannelEdgeInfo,
|
2017-08-22 09:58:59 +03:00
|
|
|
e, _ *channeldb.ChannelEdgePolicy) error {
|
2017-04-14 23:14:54 +03:00
|
|
|
|
2017-08-22 09:58:59 +03:00
|
|
|
return cb(c, e)
|
2017-03-19 21:40:25 +03:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2017-04-01 15:33:17 +03:00
|
|
|
// ForEachChannel is used to iterate over every known edge (channel) within our
|
|
|
|
// view of the channel graph.
|
|
|
|
//
|
|
|
|
// NOTE: This method is part of the ChannelGraphSource interface.
|
2017-03-19 21:40:25 +03:00
|
|
|
func (r *ChannelRouter) ForEachChannel(cb func(chanInfo *channeldb.ChannelEdgeInfo,
|
|
|
|
e1, e2 *channeldb.ChannelEdgePolicy) error) error {
|
2017-04-01 15:33:17 +03:00
|
|
|
|
2017-03-19 21:40:25 +03:00
|
|
|
return r.cfg.Graph.ForEachChannel(cb)
|
|
|
|
}
|
2017-03-27 20:00:38 +03:00
|
|
|
|
2017-04-01 15:33:17 +03:00
|
|
|
// AddProof updates the channel edge info with proof which is needed to
|
|
|
|
// properly announce the edge to the rest of the network.
|
|
|
|
//
|
|
|
|
// NOTE: This method is part of the ChannelGraphSource interface.
|
2017-03-27 20:00:38 +03:00
|
|
|
func (r *ChannelRouter) AddProof(chanID lnwire.ShortChannelID,
|
|
|
|
proof *channeldb.ChannelAuthProof) error {
|
|
|
|
|
|
|
|
info, _, _, err := r.cfg.Graph.FetchChannelEdgesByID(chanID.ToUint64())
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
info.AuthProof = proof
|
|
|
|
return r.cfg.Graph.UpdateChannelEdge(info)
|
|
|
|
}
|