routing: add new interface AdditionalEdge.
A new interface AdditionalEdge is introduced which allows us to enhance the CachedEdgePolicy with additional information. We currently only need a PayloadSize function which is then used to determine the exact payload size when building a route to adhere to the sphinx package size limit (BOLT04).
This commit is contained in:
3 files changed
+275
No files matched your search
@@ -0,0 +1,107 @@
|
||||
package routing
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/lightningnetwork/lnd/channeldb/models"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/routing/route"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrNoPayLoadSizeFunc is returned when no payload size function is
|
||||
// definied.
|
||||
ErrNoPayLoadSizeFunc = errors.New("no payloadSizeFunc defined for " +
|
||||
"additional edge")
|
||||
)
|
||||
|
||||
// AdditionalEdge is an interface which specifies additional edges which can
|
||||
// be appended to an existing route. Compared to normal edges of a route they
|
||||
// provide an explicit payload size function and are introduced because blinded
|
||||
// paths differ in their payload structure.
|
||||
type AdditionalEdge interface {
|
||||
// IntermediatePayloadSize returns the size of the payload for the
|
||||
// additional edge when being an intermediate hop in a route NOT the
|
||||
// final hop.
|
||||
IntermediatePayloadSize(amount lnwire.MilliSatoshi, expiry uint32,
|
||||
legacy bool, channelID uint64) uint64
|
||||
|
||||
// EdgePolicy returns the policy of the additional edge.
|
||||
EdgePolicy() *models.CachedEdgePolicy
|
||||
}
|
||||
|
||||
// PayloadSizeFunc defines the interface for the payload size function.
|
||||
type PayloadSizeFunc func(amount lnwire.MilliSatoshi, expiry uint32,
|
||||
legacy bool, channelID uint64) uint64
|
||||
|
||||
// PrivateEdge implements the AdditionalEdge interface. As the name implies it
|
||||
// is used for private route hints that the receiver adds for example to an
|
||||
// invoice.
|
||||
type PrivateEdge struct {
|
||||
policy *models.CachedEdgePolicy
|
||||
}
|
||||
|
||||
// EdgePolicy return the policy of the PrivateEdge.
|
||||
func (p *PrivateEdge) EdgePolicy() *models.CachedEdgePolicy {
|
||||
return p.policy
|
||||
}
|
||||
|
||||
// IntermediatePayloadSize returns the sphinx payload size defined in BOLT04 if
|
||||
// this edge were to be included in a route.
|
||||
func (p *PrivateEdge) IntermediatePayloadSize(amount lnwire.MilliSatoshi,
|
||||
expiry uint32, legacy bool, channelID uint64) uint64 {
|
||||
|
||||
hop := route.Hop{
|
||||
AmtToForward: amount,
|
||||
OutgoingTimeLock: expiry,
|
||||
LegacyPayload: legacy,
|
||||
}
|
||||
|
||||
return hop.PayloadSize(channelID)
|
||||
}
|
||||
|
||||
// BlindedEdge implements the AdditionalEdge interface. Blinded hops are viewed
|
||||
// as additional edges because they are appened at the end of a normal route.
|
||||
type BlindedEdge struct {
|
||||
policy *models.CachedEdgePolicy
|
||||
cipherText []byte
|
||||
blindingPoint *btcec.PublicKey
|
||||
}
|
||||
|
||||
// EdgePolicy return the policy of the BlindedEdge.
|
||||
func (b *BlindedEdge) EdgePolicy() *models.CachedEdgePolicy {
|
||||
return b.policy
|
||||
}
|
||||
|
||||
// IntermediatePayloadSize returns the sphinx payload size defined in BOLT04 if
|
||||
// this edge were to be included in a route.
|
||||
func (b *BlindedEdge) IntermediatePayloadSize(_ lnwire.MilliSatoshi, _ uint32,
|
||||
_ bool, _ uint64) uint64 {
|
||||
|
||||
hop := route.Hop{
|
||||
BlindingPoint: b.blindingPoint,
|
||||
LegacyPayload: false,
|
||||
EncryptedData: b.cipherText,
|
||||
}
|
||||
|
||||
// For blinded paths the next chanID is in the encrypted data tlv.
|
||||
return hop.PayloadSize(0)
|
||||
}
|
||||
|
||||
// Compile-time constraints to ensure the PrivateEdge and the BlindedEdge
|
||||
// implement the AdditionalEdge interface.
|
||||
var _ AdditionalEdge = (*PrivateEdge)(nil)
|
||||
var _ AdditionalEdge = (*BlindedEdge)(nil)
|
||||
|
||||
// defaultHopPayloadSize is the default payload size of a normal (not-blinded)
|
||||
// hop in the route.
|
||||
func defaultHopPayloadSize(amount lnwire.MilliSatoshi, expiry uint32,
|
||||
legacy bool, channelID uint64) uint64 {
|
||||
|
||||
// The payload size of a cleartext intermediate hop is equal to the
|
||||
// payload size of a private edge therefore we reuse its size function.
|
||||
edge := PrivateEdge{}
|
||||
|
||||
return edge.IntermediatePayloadSize(amount, expiry, legacy, channelID)
|
||||
}
|
||||
Reference in new issue
Block a user