htlcswitch+hop: move ForwardingInfo to hop.ForwaringInfo
This commit is contained in:
parent
83d2112e8b
commit
fc0e4be4d8
29
htlcswitch/hop/forwarding_info.go
Normal file
29
htlcswitch/hop/forwarding_info.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package hop
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ForwardingInfo contains all the information that is necessary to forward and
|
||||||
|
// incoming HTLC to the next hop encoded within a valid HopIterator instance.
|
||||||
|
// Forwarding links are to use this information to authenticate the information
|
||||||
|
// received within the incoming HTLC, to ensure that the prior hop didn't
|
||||||
|
// tamper with the end-to-end routing information at all.
|
||||||
|
type ForwardingInfo struct {
|
||||||
|
// Network is the target blockchain network that the HTLC will travel
|
||||||
|
// over next.
|
||||||
|
Network Network
|
||||||
|
|
||||||
|
// NextHop is the channel ID of the next hop. The received HTLC should
|
||||||
|
// be forwarded to this particular channel in order to continue the
|
||||||
|
// end-to-end route.
|
||||||
|
NextHop lnwire.ShortChannelID
|
||||||
|
|
||||||
|
// AmountToForward is the amount of milli-satoshis that the receiving
|
||||||
|
// node should forward to the next hop.
|
||||||
|
AmountToForward lnwire.MilliSatoshi
|
||||||
|
|
||||||
|
// OutgoingCTLV is the specified value of the CTLV timelock to be used
|
||||||
|
// in the outgoing HTLC.
|
||||||
|
OutgoingCTLV uint32
|
||||||
|
}
|
@ -24,33 +24,6 @@ var (
|
|||||||
sourceHop lnwire.ShortChannelID
|
sourceHop lnwire.ShortChannelID
|
||||||
)
|
)
|
||||||
|
|
||||||
// ForwardingInfo contains all the information that is necessary to forward and
|
|
||||||
// incoming HTLC to the next hop encoded within a valid HopIterator instance.
|
|
||||||
// Forwarding links are to use this information to authenticate the information
|
|
||||||
// received within the incoming HTLC, to ensure that the prior hop didn't
|
|
||||||
// tamper with the end-to-end routing information at all.
|
|
||||||
type ForwardingInfo struct {
|
|
||||||
// Network is the target blockchain network that the HTLC will travel
|
|
||||||
// over next.
|
|
||||||
Network hop.Network
|
|
||||||
|
|
||||||
// NextHop is the channel ID of the next hop. The received HTLC should
|
|
||||||
// be forwarded to this particular channel in order to continue the
|
|
||||||
// end-to-end route.
|
|
||||||
NextHop lnwire.ShortChannelID
|
|
||||||
|
|
||||||
// AmountToForward is the amount of milli-satoshis that the receiving
|
|
||||||
// node should forward to the next hop.
|
|
||||||
AmountToForward lnwire.MilliSatoshi
|
|
||||||
|
|
||||||
// OutgoingCTLV is the specified value of the CTLV timelock to be used
|
|
||||||
// in the outgoing HTLC.
|
|
||||||
OutgoingCTLV uint32
|
|
||||||
|
|
||||||
// TODO(roasbeef): modify sphinx logic to not just discard the
|
|
||||||
// remaining bytes, instead should include the rest as excess
|
|
||||||
}
|
|
||||||
|
|
||||||
// HopIterator is an interface that abstracts away the routing information
|
// HopIterator is an interface that abstracts away the routing information
|
||||||
// included in HTLC's which includes the entirety of the payment path of an
|
// included in HTLC's which includes the entirety of the payment path of an
|
||||||
// HTLC. This interface provides two basic method which carry out: how to
|
// HTLC. This interface provides two basic method which carry out: how to
|
||||||
@ -62,7 +35,7 @@ type HopIterator interface {
|
|||||||
// Additionally, the information encoded within the returned
|
// Additionally, the information encoded within the returned
|
||||||
// ForwardingInfo is to be used by each hop to authenticate the
|
// ForwardingInfo is to be used by each hop to authenticate the
|
||||||
// information given to it by the prior hop.
|
// information given to it by the prior hop.
|
||||||
ForwardingInstructions() (ForwardingInfo, error)
|
ForwardingInstructions() (hop.ForwardingInfo, error)
|
||||||
|
|
||||||
// ExtraOnionBlob returns the additional EOB data (if available).
|
// ExtraOnionBlob returns the additional EOB data (if available).
|
||||||
ExtraOnionBlob() []byte
|
ExtraOnionBlob() []byte
|
||||||
@ -119,7 +92,9 @@ func (r *sphinxHopIterator) EncodeNextHop(w io.Writer) error {
|
|||||||
// hop to authenticate the information given to it by the prior hop.
|
// hop to authenticate the information given to it by the prior hop.
|
||||||
//
|
//
|
||||||
// NOTE: Part of the HopIterator interface.
|
// NOTE: Part of the HopIterator interface.
|
||||||
func (r *sphinxHopIterator) ForwardingInstructions() (ForwardingInfo, error) {
|
func (r *sphinxHopIterator) ForwardingInstructions() (
|
||||||
|
hop.ForwardingInfo, error) {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
nextHop lnwire.ShortChannelID
|
nextHop lnwire.ShortChannelID
|
||||||
amt uint64
|
amt uint64
|
||||||
@ -154,24 +129,25 @@ func (r *sphinxHopIterator) ForwardingInstructions() (ForwardingInfo, error) {
|
|||||||
record.NewNextHopIDRecord(&cid),
|
record.NewNextHopIDRecord(&cid),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ForwardingInfo{}, err
|
return hop.ForwardingInfo{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = tlvStream.Decode(bytes.NewReader(
|
err = tlvStream.Decode(bytes.NewReader(
|
||||||
r.processedPacket.Payload.Payload,
|
r.processedPacket.Payload.Payload,
|
||||||
))
|
))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ForwardingInfo{}, err
|
return hop.ForwardingInfo{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
nextHop = lnwire.NewShortChanIDFromInt(cid)
|
nextHop = lnwire.NewShortChanIDFromInt(cid)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return ForwardingInfo{}, fmt.Errorf("unknown sphinx payload "+
|
return hop.ForwardingInfo{}, fmt.Errorf("unknown "+
|
||||||
"type: %v", r.processedPacket.Payload.Type)
|
"sphinx payload type: %v",
|
||||||
|
r.processedPacket.Payload.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ForwardingInfo{
|
return hop.ForwardingInfo{
|
||||||
Network: hop.BitcoinNetwork,
|
Network: hop.BitcoinNetwork,
|
||||||
NextHop: nextHop,
|
NextHop: nextHop,
|
||||||
AmountToForward: lnwire.MilliSatoshi(amt),
|
AmountToForward: lnwire.MilliSatoshi(amt),
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
sphinx "github.com/lightningnetwork/lightning-onion"
|
sphinx "github.com/lightningnetwork/lightning-onion"
|
||||||
|
"github.com/lightningnetwork/lnd/htlcswitch/hop"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
"github.com/lightningnetwork/lnd/record"
|
"github.com/lightningnetwork/lnd/record"
|
||||||
"github.com/lightningnetwork/lnd/tlv"
|
"github.com/lightningnetwork/lnd/tlv"
|
||||||
@ -29,7 +30,7 @@ func TestSphinxHopIteratorForwardingInstructions(t *testing.T) {
|
|||||||
// Next, we'll make the hop forwarding information that we should
|
// Next, we'll make the hop forwarding information that we should
|
||||||
// extract each type, no matter the payload type.
|
// extract each type, no matter the payload type.
|
||||||
nextAddrInt := binary.BigEndian.Uint64(hopData.NextAddress[:])
|
nextAddrInt := binary.BigEndian.Uint64(hopData.NextAddress[:])
|
||||||
expectedFwdInfo := ForwardingInfo{
|
expectedFwdInfo := hop.ForwardingInfo{
|
||||||
NextHop: lnwire.NewShortChanIDFromInt(nextAddrInt),
|
NextHop: lnwire.NewShortChanIDFromInt(nextAddrInt),
|
||||||
AmountToForward: lnwire.MilliSatoshi(hopData.ForwardAmount),
|
AmountToForward: lnwire.MilliSatoshi(hopData.ForwardAmount),
|
||||||
OutgoingCTLV: hopData.OutgoingCltv,
|
OutgoingCTLV: hopData.OutgoingCltv,
|
||||||
@ -53,7 +54,7 @@ func TestSphinxHopIteratorForwardingInstructions(t *testing.T) {
|
|||||||
|
|
||||||
var testCases = []struct {
|
var testCases = []struct {
|
||||||
sphinxPacket *sphinx.ProcessedPacket
|
sphinxPacket *sphinx.ProcessedPacket
|
||||||
expectedFwdInfo ForwardingInfo
|
expectedFwdInfo hop.ForwardingInfo
|
||||||
}{
|
}{
|
||||||
// A regular legacy payload that signals more hops.
|
// A regular legacy payload that signals more hops.
|
||||||
{
|
{
|
||||||
|
@ -16,6 +16,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
"github.com/lightningnetwork/lnd/contractcourt"
|
"github.com/lightningnetwork/lnd/contractcourt"
|
||||||
"github.com/lightningnetwork/lnd/htlcswitch/hodl"
|
"github.com/lightningnetwork/lnd/htlcswitch/hodl"
|
||||||
|
"github.com/lightningnetwork/lnd/htlcswitch/hop"
|
||||||
"github.com/lightningnetwork/lnd/input"
|
"github.com/lightningnetwork/lnd/input"
|
||||||
"github.com/lightningnetwork/lnd/invoices"
|
"github.com/lightningnetwork/lnd/invoices"
|
||||||
"github.com/lightningnetwork/lnd/lnpeer"
|
"github.com/lightningnetwork/lnd/lnpeer"
|
||||||
@ -2849,7 +2850,7 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
|
|||||||
// processExitHop handles an htlc for which this link is the exit hop. It
|
// processExitHop handles an htlc for which this link is the exit hop. It
|
||||||
// returns a boolean indicating whether the commitment tx needs an update.
|
// returns a boolean indicating whether the commitment tx needs an update.
|
||||||
func (l *channelLink) processExitHop(pd *lnwallet.PaymentDescriptor,
|
func (l *channelLink) processExitHop(pd *lnwallet.PaymentDescriptor,
|
||||||
obfuscator ErrorEncrypter, fwdInfo ForwardingInfo,
|
obfuscator ErrorEncrypter, fwdInfo hop.ForwardingInfo,
|
||||||
heightNow uint32, eob []byte) (bool, error) {
|
heightNow uint32, eob []byte) (bool, error) {
|
||||||
|
|
||||||
// If hodl.ExitSettle is requested, we will not validate the final hop's
|
// If hodl.ExitSettle is requested, we will not validate the final hop's
|
||||||
|
@ -4308,7 +4308,7 @@ func generateHtlcAndInvoice(t *testing.T,
|
|||||||
|
|
||||||
htlcAmt := lnwire.NewMSatFromSatoshis(10000)
|
htlcAmt := lnwire.NewMSatFromSatoshis(10000)
|
||||||
htlcExpiry := testStartingHeight + testInvoiceCltvExpiry
|
htlcExpiry := testStartingHeight + testInvoiceCltvExpiry
|
||||||
hops := []ForwardingInfo{
|
hops := []hop.ForwardingInfo{
|
||||||
{
|
{
|
||||||
Network: hop.BitcoinNetwork,
|
Network: hop.BitcoinNetwork,
|
||||||
NextHop: exitHop,
|
NextHop: exitHop,
|
||||||
|
@ -269,14 +269,16 @@ func (s *mockServer) QuitSignal() <-chan struct{} {
|
|||||||
// mockHopIterator represents the test version of hop iterator which instead
|
// mockHopIterator represents the test version of hop iterator which instead
|
||||||
// of encrypting the path in onion blob just stores the path as a list of hops.
|
// of encrypting the path in onion blob just stores the path as a list of hops.
|
||||||
type mockHopIterator struct {
|
type mockHopIterator struct {
|
||||||
hops []ForwardingInfo
|
hops []hop.ForwardingInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMockHopIterator(hops ...ForwardingInfo) HopIterator {
|
func newMockHopIterator(hops ...hop.ForwardingInfo) HopIterator {
|
||||||
return &mockHopIterator{hops: hops}
|
return &mockHopIterator{hops: hops}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *mockHopIterator) ForwardingInstructions() (ForwardingInfo, error) {
|
func (r *mockHopIterator) ForwardingInstructions() (
|
||||||
|
hop.ForwardingInfo, error) {
|
||||||
|
|
||||||
h := r.hops[0]
|
h := r.hops[0]
|
||||||
r.hops = r.hops[1:]
|
r.hops = r.hops[1:]
|
||||||
return h, nil
|
return h, nil
|
||||||
@ -301,7 +303,7 @@ func (r *mockHopIterator) EncodeNextHop(w io.Writer) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, hop := range r.hops {
|
for _, hop := range r.hops {
|
||||||
if err := hop.encode(w); err != nil {
|
if err := encodeFwdInfo(w, &hop); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -309,7 +311,7 @@ func (r *mockHopIterator) EncodeNextHop(w io.Writer) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *ForwardingInfo) encode(w io.Writer) error {
|
func encodeFwdInfo(w io.Writer, f *hop.ForwardingInfo) error {
|
||||||
if _, err := w.Write([]byte{byte(f.Network)}); err != nil {
|
if _, err := w.Write([]byte{byte(f.Network)}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -430,10 +432,10 @@ func (p *mockIteratorDecoder) DecodeHopIterator(r io.Reader, rHash []byte,
|
|||||||
}
|
}
|
||||||
hopLength := binary.BigEndian.Uint32(b[:])
|
hopLength := binary.BigEndian.Uint32(b[:])
|
||||||
|
|
||||||
hops := make([]ForwardingInfo, hopLength)
|
hops := make([]hop.ForwardingInfo, hopLength)
|
||||||
for i := uint32(0); i < hopLength; i++ {
|
for i := uint32(0); i < hopLength; i++ {
|
||||||
f := &ForwardingInfo{}
|
f := &hop.ForwardingInfo{}
|
||||||
if err := f.decode(r); err != nil {
|
if err := decodeFwdInfo(r, f); err != nil {
|
||||||
return nil, lnwire.CodeTemporaryChannelFailure
|
return nil, lnwire.CodeTemporaryChannelFailure
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -481,7 +483,7 @@ func (p *mockIteratorDecoder) DecodeHopIterators(id []byte,
|
|||||||
return resps, nil
|
return resps, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *ForwardingInfo) decode(r io.Reader) error {
|
func decodeFwdInfo(r io.Reader, f *hop.ForwardingInfo) error {
|
||||||
var net [1]byte
|
var net [1]byte
|
||||||
if _, err := r.Read(net[:]); err != nil {
|
if _, err := r.Read(net[:]); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -597,7 +597,9 @@ func generatePayment(invoiceAmt, htlcAmt lnwire.MilliSatoshi, timelock uint32,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// generateRoute generates the path blob by given array of peers.
|
// generateRoute generates the path blob by given array of peers.
|
||||||
func generateRoute(hops ...ForwardingInfo) ([lnwire.OnionPacketSize]byte, error) {
|
func generateRoute(hops ...hop.ForwardingInfo) (
|
||||||
|
[lnwire.OnionPacketSize]byte, error) {
|
||||||
|
|
||||||
var blob [lnwire.OnionPacketSize]byte
|
var blob [lnwire.OnionPacketSize]byte
|
||||||
if len(hops) == 0 {
|
if len(hops) == 0 {
|
||||||
return blob, errors.New("empty path")
|
return blob, errors.New("empty path")
|
||||||
@ -636,12 +638,13 @@ type threeHopNetwork struct {
|
|||||||
// also the time lock value needed to route an HTLC with the target amount over
|
// also the time lock value needed to route an HTLC with the target amount over
|
||||||
// the specified path.
|
// the specified path.
|
||||||
func generateHops(payAmt lnwire.MilliSatoshi, startingHeight uint32,
|
func generateHops(payAmt lnwire.MilliSatoshi, startingHeight uint32,
|
||||||
path ...*channelLink) (lnwire.MilliSatoshi, uint32, []ForwardingInfo) {
|
path ...*channelLink) (lnwire.MilliSatoshi, uint32,
|
||||||
|
[]hop.ForwardingInfo) {
|
||||||
|
|
||||||
totalTimelock := startingHeight
|
totalTimelock := startingHeight
|
||||||
runningAmt := payAmt
|
runningAmt := payAmt
|
||||||
|
|
||||||
hops := make([]ForwardingInfo, len(path))
|
hops := make([]hop.ForwardingInfo, len(path))
|
||||||
for i := len(path) - 1; i >= 0; i-- {
|
for i := len(path) - 1; i >= 0; i-- {
|
||||||
// If this is the last hop, then the next hop is the special
|
// If this is the last hop, then the next hop is the special
|
||||||
// "exit node". Otherwise, we look to the "prior" hop.
|
// "exit node". Otherwise, we look to the "prior" hop.
|
||||||
@ -680,7 +683,7 @@ func generateHops(payAmt lnwire.MilliSatoshi, startingHeight uint32,
|
|||||||
amount = runningAmt - fee
|
amount = runningAmt - fee
|
||||||
}
|
}
|
||||||
|
|
||||||
hops[i] = ForwardingInfo{
|
hops[i] = hop.ForwardingInfo{
|
||||||
Network: hop.BitcoinNetwork,
|
Network: hop.BitcoinNetwork,
|
||||||
NextHop: nextHop,
|
NextHop: nextHop,
|
||||||
AmountToForward: amount,
|
AmountToForward: amount,
|
||||||
@ -732,7 +735,7 @@ func waitForPayFuncResult(payFunc func() error, d time.Duration) error {
|
|||||||
// * from Alice to Carol through the Bob
|
// * from Alice to Carol through the Bob
|
||||||
// * from Alice to some another peer through the Bob
|
// * from Alice to some another peer through the Bob
|
||||||
func makePayment(sendingPeer, receivingPeer lnpeer.Peer,
|
func makePayment(sendingPeer, receivingPeer lnpeer.Peer,
|
||||||
firstHop lnwire.ShortChannelID, hops []ForwardingInfo,
|
firstHop lnwire.ShortChannelID, hops []hop.ForwardingInfo,
|
||||||
invoiceAmt, htlcAmt lnwire.MilliSatoshi,
|
invoiceAmt, htlcAmt lnwire.MilliSatoshi,
|
||||||
timelock uint32) *paymentResponse {
|
timelock uint32) *paymentResponse {
|
||||||
|
|
||||||
@ -766,7 +769,7 @@ func makePayment(sendingPeer, receivingPeer lnpeer.Peer,
|
|||||||
// preparePayment creates an invoice at the receivingPeer and returns a function
|
// preparePayment creates an invoice at the receivingPeer and returns a function
|
||||||
// that, when called, launches the payment from the sendingPeer.
|
// that, when called, launches the payment from the sendingPeer.
|
||||||
func preparePayment(sendingPeer, receivingPeer lnpeer.Peer,
|
func preparePayment(sendingPeer, receivingPeer lnpeer.Peer,
|
||||||
firstHop lnwire.ShortChannelID, hops []ForwardingInfo,
|
firstHop lnwire.ShortChannelID, hops []hop.ForwardingInfo,
|
||||||
invoiceAmt, htlcAmt lnwire.MilliSatoshi,
|
invoiceAmt, htlcAmt lnwire.MilliSatoshi,
|
||||||
timelock uint32) (*channeldb.Invoice, func() error, error) {
|
timelock uint32) (*channeldb.Invoice, func() error, error) {
|
||||||
|
|
||||||
@ -1247,7 +1250,7 @@ func (n *twoHopNetwork) stop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *twoHopNetwork) makeHoldPayment(sendingPeer, receivingPeer lnpeer.Peer,
|
func (n *twoHopNetwork) makeHoldPayment(sendingPeer, receivingPeer lnpeer.Peer,
|
||||||
firstHop lnwire.ShortChannelID, hops []ForwardingInfo,
|
firstHop lnwire.ShortChannelID, hops []hop.ForwardingInfo,
|
||||||
invoiceAmt, htlcAmt lnwire.MilliSatoshi,
|
invoiceAmt, htlcAmt lnwire.MilliSatoshi,
|
||||||
timelock uint32, preimage lntypes.Preimage) chan error {
|
timelock uint32, preimage lntypes.Preimage) chan error {
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user