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 06:20:26 +01:00
|
|
|
package routing
|
|
|
|
|
2017-03-19 19:40:25 +01:00
|
|
|
import "github.com/go-errors/errors"
|
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 06:20:26 +01:00
|
|
|
|
2017-05-15 04:27:14 +02:00
|
|
|
// errorCode is used to represent the various errors that can occur within this
|
|
|
|
// package.
|
2017-03-19 19:40:25 +01:00
|
|
|
type errorCode uint8
|
|
|
|
|
|
|
|
const (
|
|
|
|
// ErrOutdated is returned when the routing update already have
|
2018-08-20 14:28:09 +02:00
|
|
|
// been applied, or a newer update is already known.
|
2020-01-15 20:28:48 +01:00
|
|
|
ErrOutdated errorCode = iota
|
2017-03-19 19:40:25 +01:00
|
|
|
|
|
|
|
// ErrIgnored is returned when the update have been ignored because
|
2017-07-14 21:32:00 +02:00
|
|
|
// this update can't bring us something new, or because a node
|
|
|
|
// announcement was given for node not found in any channel.
|
2017-03-19 19:40:25 +01:00
|
|
|
ErrIgnored
|
2021-04-21 01:22:36 +02:00
|
|
|
|
|
|
|
// ErrChannelSpent is returned when we go to validate a channel, but
|
|
|
|
// the purported funding output has actually already been spent on
|
|
|
|
// chain.
|
|
|
|
ErrChannelSpent
|
2021-04-21 01:23:10 +02:00
|
|
|
|
|
|
|
// ErrNoFundingTransaction is returned when we are unable to find the
|
|
|
|
// funding transaction described by the short channel ID on chain.
|
|
|
|
ErrNoFundingTransaction
|
2021-04-23 01:41:15 +02:00
|
|
|
|
|
|
|
// ErrInvalidFundingOutput is returned if the channle funding output
|
|
|
|
// fails validation.
|
|
|
|
ErrInvalidFundingOutput
|
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 06:20:26 +01:00
|
|
|
)
|
2017-03-19 19:40:25 +01:00
|
|
|
|
|
|
|
// routerError is a structure that represent the error inside the routing package,
|
|
|
|
// this structure carries additional information about error code in order to
|
|
|
|
// be able distinguish errors outside of the current package.
|
|
|
|
type routerError struct {
|
|
|
|
err *errors.Error
|
|
|
|
code errorCode
|
|
|
|
}
|
|
|
|
|
|
|
|
// Error represents errors as the string
|
|
|
|
// NOTE: Part of the error interface.
|
|
|
|
func (e *routerError) Error() string {
|
|
|
|
return e.err.Error()
|
|
|
|
}
|
|
|
|
|
|
|
|
// A compile time check to ensure routerError implements the error interface.
|
|
|
|
var _ error = (*routerError)(nil)
|
|
|
|
|
2018-04-18 04:02:04 +02:00
|
|
|
// newErrf creates a routerError by the given error formatted description and
|
2017-03-19 19:40:25 +01:00
|
|
|
// its corresponding error code.
|
|
|
|
func newErrf(code errorCode, format string, a ...interface{}) *routerError {
|
|
|
|
return &routerError{
|
|
|
|
code: code,
|
|
|
|
err: errors.Errorf(format, a...),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsError is a helper function which is needed to have ability to check that
|
|
|
|
// returned error has specific error code.
|
|
|
|
func IsError(e interface{}, codes ...errorCode) bool {
|
|
|
|
err, ok := e.(*routerError)
|
|
|
|
if !ok {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, code := range codes {
|
|
|
|
if err.code == code {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|