Merge pull request #3466 from cfromknecht/htlcswitch-hop
htlcswitch/hop: new package for hop payload parsing/encapsulation
This commit is contained in:
commit
6638e1ddde
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
"github.com/go-errors/errors"
|
"github.com/go-errors/errors"
|
||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
|
"github.com/lightningnetwork/lnd/htlcswitch/hop"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -311,7 +312,7 @@ func (cm *circuitMap) restoreMemState() error {
|
|||||||
// documented case of stray keystones emerges for
|
// documented case of stray keystones emerges for
|
||||||
// forwarded payments, this check should be removed, but
|
// forwarded payments, this check should be removed, but
|
||||||
// with extreme caution.
|
// with extreme caution.
|
||||||
if strayKeystone.OutKey.ChanID != sourceHop {
|
if strayKeystone.OutKey.ChanID != hop.Source {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,9 +397,9 @@ func (cm *circuitMap) trimAllOpenCircuits() error {
|
|||||||
|
|
||||||
// First, skip any channels that have not been assigned their
|
// First, skip any channels that have not been assigned their
|
||||||
// final channel identifier, otherwise we would try to trim
|
// final channel identifier, otherwise we would try to trim
|
||||||
// htlcs belonging to the all-zero, sourceHop ID.
|
// htlcs belonging to the all-zero, hop.Source ID.
|
||||||
chanID := activeChannel.ShortChanID()
|
chanID := activeChannel.ShortChanID()
|
||||||
if chanID == sourceHop {
|
if chanID == hop.Source {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
28
htlcswitch/hop/network.go
Normal file
28
htlcswitch/hop/network.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package hop
|
||||||
|
|
||||||
|
// Network indicates the blockchain network that is intended to be the next hop
|
||||||
|
// for a forwarded HTLC. The existence of this field within the ForwardingInfo
|
||||||
|
// struct enables the ability for HTLC to cross chain-boundaries at will.
|
||||||
|
type Network uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
// BitcoinNetwork denotes that an HTLC is to be forwarded along the
|
||||||
|
// Bitcoin link with the specified short channel ID.
|
||||||
|
BitcoinNetwork Network = iota
|
||||||
|
|
||||||
|
// LitecoinNetwork denotes that an HTLC is to be forwarded along the
|
||||||
|
// Litecoin link with the specified short channel ID.
|
||||||
|
LitecoinNetwork
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns the string representation of the target Network.
|
||||||
|
func (c Network) String() string {
|
||||||
|
switch c {
|
||||||
|
case BitcoinNetwork:
|
||||||
|
return "Bitcoin"
|
||||||
|
case LitecoinNetwork:
|
||||||
|
return "Litecoin"
|
||||||
|
default:
|
||||||
|
return "Kekcoin"
|
||||||
|
}
|
||||||
|
}
|
75
htlcswitch/hop/payload.go
Normal file
75
htlcswitch/hop/payload.go
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
package hop
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/lightningnetwork/lightning-onion"
|
||||||
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
|
"github.com/lightningnetwork/lnd/record"
|
||||||
|
"github.com/lightningnetwork/lnd/tlv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Payload encapsulates all information delivered to a hop in an onion payload.
|
||||||
|
// A Hop can represent either a TLV or legacy payload. The primary forwarding
|
||||||
|
// instruction can be accessed via ForwardingInfo, and additional records can be
|
||||||
|
// accessed by other member functions.
|
||||||
|
type Payload struct {
|
||||||
|
// FwdInfo holds the basic parameters required for HTLC forwarding, e.g.
|
||||||
|
// amount, cltv, and next hop.
|
||||||
|
FwdInfo ForwardingInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLegacyPayload builds a Payload from the amount, cltv, and next hop
|
||||||
|
// parameters provided by leegacy onion payloads.
|
||||||
|
func NewLegacyPayload(f *sphinx.HopData) *Payload {
|
||||||
|
nextHop := binary.BigEndian.Uint64(f.NextAddress[:])
|
||||||
|
|
||||||
|
return &Payload{
|
||||||
|
FwdInfo: ForwardingInfo{
|
||||||
|
Network: BitcoinNetwork,
|
||||||
|
NextHop: lnwire.NewShortChanIDFromInt(nextHop),
|
||||||
|
AmountToForward: lnwire.MilliSatoshi(f.ForwardAmount),
|
||||||
|
OutgoingCTLV: f.OutgoingCltv,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPayloadFromReader builds a new Hop from the passed io.Reader. The reader
|
||||||
|
// should correspond to the bytes encapsulated in a TLV onion payload.
|
||||||
|
func NewPayloadFromReader(r io.Reader) (*Payload, error) {
|
||||||
|
var (
|
||||||
|
cid uint64
|
||||||
|
amt uint64
|
||||||
|
cltv uint32
|
||||||
|
)
|
||||||
|
|
||||||
|
tlvStream, err := tlv.NewStream(
|
||||||
|
record.NewAmtToFwdRecord(&amt),
|
||||||
|
record.NewLockTimeRecord(&cltv),
|
||||||
|
record.NewNextHopIDRecord(&cid),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tlvStream.Decode(r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Payload{
|
||||||
|
FwdInfo: ForwardingInfo{
|
||||||
|
Network: BitcoinNetwork,
|
||||||
|
NextHop: lnwire.NewShortChanIDFromInt(cid),
|
||||||
|
AmountToForward: lnwire.MilliSatoshi(amt),
|
||||||
|
OutgoingCTLV: cltv,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ForwardingInfo returns the basic parameters required for HTLC forwarding,
|
||||||
|
// e.g. amount, cltv, and next hop.
|
||||||
|
func (h *Payload) ForwardingInfo() ForwardingInfo {
|
||||||
|
return h.FwdInfo
|
||||||
|
}
|
13
htlcswitch/hop/type.go
Normal file
13
htlcswitch/hop/type.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package hop
|
||||||
|
|
||||||
|
import "github.com/lightningnetwork/lnd/lnwire"
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Exit is a special "hop" denoting that an incoming HTLC is meant to
|
||||||
|
// pay finally to the receiving node.
|
||||||
|
Exit lnwire.ShortChannelID
|
||||||
|
|
||||||
|
// Source is a sentinel "hop" denoting that an incoming HTLC is
|
||||||
|
// initiated by our own switch.
|
||||||
|
Source lnwire.ShortChannelID
|
||||||
|
)
|
@ -2,82 +2,15 @@ package htlcswitch
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec"
|
"github.com/btcsuite/btcd/btcec"
|
||||||
"github.com/lightningnetwork/lightning-onion"
|
"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/tlv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NetworkHop indicates the blockchain network that is intended to be the next
|
|
||||||
// hop for a forwarded HTLC. The existence of this field within the
|
|
||||||
// ForwardingInfo struct enables the ability for HTLC to cross chain-boundaries
|
|
||||||
// at will.
|
|
||||||
type NetworkHop uint8
|
|
||||||
|
|
||||||
const (
|
|
||||||
// BitcoinHop denotes that an HTLC is to be forwarded along the Bitcoin
|
|
||||||
// link with the specified short channel ID.
|
|
||||||
BitcoinHop NetworkHop = iota
|
|
||||||
|
|
||||||
// LitecoinHop denotes that an HTLC is to be forwarded along the
|
|
||||||
// Litecoin link with the specified short channel ID.
|
|
||||||
LitecoinHop
|
|
||||||
)
|
|
||||||
|
|
||||||
// String returns the string representation of the target NetworkHop.
|
|
||||||
func (c NetworkHop) String() string {
|
|
||||||
switch c {
|
|
||||||
case BitcoinHop:
|
|
||||||
return "Bitcoin"
|
|
||||||
case LitecoinHop:
|
|
||||||
return "Litecoin"
|
|
||||||
default:
|
|
||||||
return "Kekcoin"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
// exitHop is a special "hop" which denotes that an incoming HTLC is
|
|
||||||
// meant to pay finally to the receiving node.
|
|
||||||
exitHop lnwire.ShortChannelID
|
|
||||||
|
|
||||||
// sourceHop is a sentinel value denoting that an incoming HTLC is
|
|
||||||
// initiated by our own switch.
|
|
||||||
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 NetworkHop
|
|
||||||
|
|
||||||
// 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
|
||||||
@ -89,7 +22,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
|
||||||
@ -146,64 +79,35 @@ 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() (
|
||||||
var (
|
hop.ForwardingInfo, error) {
|
||||||
nextHop lnwire.ShortChannelID
|
|
||||||
amt uint64
|
|
||||||
cltv uint32
|
|
||||||
)
|
|
||||||
|
|
||||||
switch r.processedPacket.Payload.Type {
|
switch r.processedPacket.Payload.Type {
|
||||||
// If this is the legacy payload, then we'll extract the information
|
// If this is the legacy payload, then we'll extract the information
|
||||||
// directly from the pre-populated ForwardingInstructions field.
|
// directly from the pre-populated ForwardingInstructions field.
|
||||||
case sphinx.PayloadLegacy:
|
case sphinx.PayloadLegacy:
|
||||||
fwdInst := r.processedPacket.ForwardingInstructions
|
fwdInst := r.processedPacket.ForwardingInstructions
|
||||||
|
p := hop.NewLegacyPayload(fwdInst)
|
||||||
|
|
||||||
switch r.processedPacket.Action {
|
return p.ForwardingInfo(), nil
|
||||||
case sphinx.ExitNode:
|
|
||||||
nextHop = exitHop
|
|
||||||
case sphinx.MoreHops:
|
|
||||||
s := binary.BigEndian.Uint64(fwdInst.NextAddress[:])
|
|
||||||
nextHop = lnwire.NewShortChanIDFromInt(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
amt = fwdInst.ForwardAmount
|
|
||||||
cltv = fwdInst.OutgoingCltv
|
|
||||||
|
|
||||||
// Otherwise, if this is the TLV payload, then we'll make a new stream
|
// Otherwise, if this is the TLV payload, then we'll make a new stream
|
||||||
// to decode only what we need to make routing decisions.
|
// to decode only what we need to make routing decisions.
|
||||||
case sphinx.PayloadTLV:
|
case sphinx.PayloadTLV:
|
||||||
var cid uint64
|
p, err := hop.NewPayloadFromReader(bytes.NewReader(
|
||||||
|
|
||||||
tlvStream, err := tlv.NewStream(
|
|
||||||
record.NewAmtToFwdRecord(&amt),
|
|
||||||
record.NewLockTimeRecord(&cltv),
|
|
||||||
record.NewNextHopIDRecord(&cid),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return ForwardingInfo{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
return p.ForwardingInfo(), nil
|
||||||
|
|
||||||
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{
|
|
||||||
Network: BitcoinHop,
|
|
||||||
NextHop: nextHop,
|
|
||||||
AmountToForward: lnwire.MilliSatoshi(amt),
|
|
||||||
OutgoingCTLV: cltv,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtraOnionBlob returns the additional EOB data (if available).
|
// ExtraOnionBlob returns the additional EOB data (if available).
|
||||||
|
@ -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"
|
||||||
@ -436,8 +437,8 @@ func (l *channelLink) Start() error {
|
|||||||
// off point, since all indexes below that are committed. This action
|
// off point, since all indexes below that are committed. This action
|
||||||
// is only performed if the link's final short channel ID has been
|
// is only performed if the link's final short channel ID has been
|
||||||
// assigned, otherwise we would try to trim the htlcs belonging to the
|
// assigned, otherwise we would try to trim the htlcs belonging to the
|
||||||
// all-zero, sourceHop ID.
|
// all-zero, hop.Source ID.
|
||||||
if l.ShortChanID() != sourceHop {
|
if l.ShortChanID() != hop.Source {
|
||||||
localHtlcIndex, err := l.channel.NextLocalHtlcIndex()
|
localHtlcIndex, err := l.channel.NextLocalHtlcIndex()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to retrieve next local "+
|
return fmt.Errorf("unable to retrieve next local "+
|
||||||
@ -535,7 +536,7 @@ func (l *channelLink) WaitForShutdown() {
|
|||||||
// the all-zero source ID, meaning that the channel has had its ID finalized.
|
// the all-zero source ID, meaning that the channel has had its ID finalized.
|
||||||
func (l *channelLink) EligibleToForward() bool {
|
func (l *channelLink) EligibleToForward() bool {
|
||||||
return l.channel.RemoteNextRevocation() != nil &&
|
return l.channel.RemoteNextRevocation() != nil &&
|
||||||
l.ShortChanID() != sourceHop
|
l.ShortChanID() != hop.Source
|
||||||
}
|
}
|
||||||
|
|
||||||
// sampleNetworkFee samples the current fee rate on the network to get into the
|
// sampleNetworkFee samples the current fee rate on the network to get into the
|
||||||
@ -961,7 +962,7 @@ func (l *channelLink) htlcManager() {
|
|||||||
// only attempt to resolve packages if our short chan id indicates that
|
// only attempt to resolve packages if our short chan id indicates that
|
||||||
// the channel is not pending, otherwise we should have no htlcs to
|
// the channel is not pending, otherwise we should have no htlcs to
|
||||||
// reforward.
|
// reforward.
|
||||||
if l.ShortChanID() != sourceHop {
|
if l.ShortChanID() != hop.Source {
|
||||||
if err := l.resolveFwdPkgs(); err != nil {
|
if err := l.resolveFwdPkgs(); err != nil {
|
||||||
l.fail(LinkFailureError{code: ErrInternalError},
|
l.fail(LinkFailureError{code: ErrInternalError},
|
||||||
"unable to resolve fwd pkgs: %v", err)
|
"unable to resolve fwd pkgs: %v", err)
|
||||||
@ -2075,7 +2076,7 @@ func (l *channelLink) UpdateShortChanID() (lnwire.ShortChannelID, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
l.errorf("unable to refresh short_chan_id for chan_id=%v: %v",
|
l.errorf("unable to refresh short_chan_id for chan_id=%v: %v",
|
||||||
chanID, err)
|
chanID, err)
|
||||||
return sourceHop, err
|
return hop.Source, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sid := l.channel.ShortChanID()
|
sid := l.channel.ShortChanID()
|
||||||
@ -2674,7 +2675,7 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch fwdInfo.NextHop {
|
switch fwdInfo.NextHop {
|
||||||
case exitHop:
|
case hop.Exit:
|
||||||
updated, err := l.processExitHop(
|
updated, err := l.processExitHop(
|
||||||
pd, obfuscator, fwdInfo, heightNow,
|
pd, obfuscator, fwdInfo, heightNow,
|
||||||
chanIterator.ExtraOnionBlob(),
|
chanIterator.ExtraOnionBlob(),
|
||||||
@ -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
|
||||||
|
@ -26,6 +26,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/lnpeer"
|
"github.com/lightningnetwork/lnd/lnpeer"
|
||||||
"github.com/lightningnetwork/lnd/lntypes"
|
"github.com/lightningnetwork/lnd/lntypes"
|
||||||
@ -1936,7 +1937,7 @@ func TestChannelLinkBandwidthConsistency(t *testing.T) {
|
|||||||
}
|
}
|
||||||
addPkt := htlcPacket{
|
addPkt := htlcPacket{
|
||||||
htlc: htlc,
|
htlc: htlc,
|
||||||
incomingChanID: sourceHop,
|
incomingChanID: hop.Source,
|
||||||
incomingHTLCID: 0,
|
incomingHTLCID: 0,
|
||||||
obfuscator: NewMockObfuscator(),
|
obfuscator: NewMockObfuscator(),
|
||||||
}
|
}
|
||||||
@ -2016,7 +2017,7 @@ func TestChannelLinkBandwidthConsistency(t *testing.T) {
|
|||||||
}
|
}
|
||||||
addPkt = htlcPacket{
|
addPkt = htlcPacket{
|
||||||
htlc: htlc,
|
htlc: htlc,
|
||||||
incomingChanID: sourceHop,
|
incomingChanID: hop.Source,
|
||||||
incomingHTLCID: 1,
|
incomingHTLCID: 1,
|
||||||
obfuscator: NewMockObfuscator(),
|
obfuscator: NewMockObfuscator(),
|
||||||
}
|
}
|
||||||
@ -2534,7 +2535,7 @@ func genAddsAndCircuits(numHtlcs int, htlc *lnwire.UpdateAddHTLC) (
|
|||||||
for i := 0; i < numHtlcs; i++ {
|
for i := 0; i < numHtlcs; i++ {
|
||||||
addPkt := htlcPacket{
|
addPkt := htlcPacket{
|
||||||
htlc: htlc,
|
htlc: htlc,
|
||||||
incomingChanID: sourceHop,
|
incomingChanID: hop.Source,
|
||||||
incomingHTLCID: uint64(i),
|
incomingHTLCID: uint64(i),
|
||||||
obfuscator: NewMockObfuscator(),
|
obfuscator: NewMockObfuscator(),
|
||||||
}
|
}
|
||||||
@ -4307,10 +4308,10 @@ 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: BitcoinHop,
|
Network: hop.BitcoinNetwork,
|
||||||
NextHop: exitHop,
|
NextHop: hop.Exit,
|
||||||
AmountToForward: htlcAmt,
|
AmountToForward: htlcAmt,
|
||||||
OutgoingCTLV: uint32(htlcExpiry),
|
OutgoingCTLV: uint32(htlcExpiry),
|
||||||
},
|
},
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||||
"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/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"
|
||||||
@ -268,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
|
||||||
@ -300,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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -308,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
|
||||||
}
|
}
|
||||||
@ -429,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
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -480,12 +483,12 @@ 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
|
||||||
}
|
}
|
||||||
f.Network = NetworkHop(net[0])
|
f.Network = hop.Network(net[0])
|
||||||
|
|
||||||
if err := binary.Read(r, binary.BigEndian, &f.NextHop); err != nil {
|
if err := binary.Read(r, binary.BigEndian, &f.NextHop); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -16,6 +16,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||||
"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/hop"
|
||||||
"github.com/lightningnetwork/lnd/lntypes"
|
"github.com/lightningnetwork/lnd/lntypes"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
@ -354,7 +355,7 @@ func (s *Switch) GetPaymentResult(paymentID uint64, paymentHash lntypes.Hash,
|
|||||||
nChan <-chan *networkResult
|
nChan <-chan *networkResult
|
||||||
err error
|
err error
|
||||||
outKey = CircuitKey{
|
outKey = CircuitKey{
|
||||||
ChanID: sourceHop,
|
ChanID: hop.Source,
|
||||||
HtlcID: paymentID,
|
HtlcID: paymentID,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -428,7 +429,7 @@ func (s *Switch) SendHTLC(firstHop lnwire.ShortChannelID, paymentID uint64,
|
|||||||
// this stage it means that packet haven't left boundaries of our
|
// this stage it means that packet haven't left boundaries of our
|
||||||
// system and something wrong happened.
|
// system and something wrong happened.
|
||||||
packet := &htlcPacket{
|
packet := &htlcPacket{
|
||||||
incomingChanID: sourceHop,
|
incomingChanID: hop.Source,
|
||||||
incomingHTLCID: paymentID,
|
incomingHTLCID: paymentID,
|
||||||
outgoingChanID: firstHop,
|
outgoingChanID: firstHop,
|
||||||
htlc: htlc,
|
htlc: htlc,
|
||||||
@ -513,7 +514,7 @@ func (s *Switch) forward(packet *htlcPacket) error {
|
|||||||
return ErrDuplicateAdd
|
return ErrDuplicateAdd
|
||||||
|
|
||||||
case len(actions.Fails) == 1:
|
case len(actions.Fails) == 1:
|
||||||
if packet.incomingChanID == sourceHop {
|
if packet.incomingChanID == hop.Source {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1031,14 +1032,14 @@ func (s *Switch) handlePacketForward(packet *htlcPacket) error {
|
|||||||
case *lnwire.UpdateAddHTLC:
|
case *lnwire.UpdateAddHTLC:
|
||||||
// Check if the node is set to reject all onward HTLCs and also make
|
// Check if the node is set to reject all onward HTLCs and also make
|
||||||
// sure that HTLC is not from the source node.
|
// sure that HTLC is not from the source node.
|
||||||
if s.cfg.RejectHTLC && packet.incomingChanID != sourceHop {
|
if s.cfg.RejectHTLC && packet.incomingChanID != hop.Source {
|
||||||
failure := &lnwire.FailChannelDisabled{}
|
failure := &lnwire.FailChannelDisabled{}
|
||||||
addErr := fmt.Errorf("unable to forward any htlcs")
|
addErr := fmt.Errorf("unable to forward any htlcs")
|
||||||
|
|
||||||
return s.failAddPacket(packet, failure, addErr)
|
return s.failAddPacket(packet, failure, addErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if packet.incomingChanID == sourceHop {
|
if packet.incomingChanID == hop.Source {
|
||||||
// A blank incomingChanID indicates that this is
|
// A blank incomingChanID indicates that this is
|
||||||
// a pending user-initiated payment.
|
// a pending user-initiated payment.
|
||||||
return s.handleLocalDispatch(packet)
|
return s.handleLocalDispatch(packet)
|
||||||
@ -1080,7 +1081,7 @@ func (s *Switch) handlePacketForward(packet *htlcPacket) error {
|
|||||||
|
|
||||||
// If the link doesn't yet have a source chan ID, then
|
// If the link doesn't yet have a source chan ID, then
|
||||||
// we'll skip it as well.
|
// we'll skip it as well.
|
||||||
case link.ShortChanID() == sourceHop:
|
case link.ShortChanID() == hop.Source:
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1222,7 +1223,7 @@ func (s *Switch) handlePacketForward(packet *htlcPacket) error {
|
|||||||
//
|
//
|
||||||
// TODO(roasbeef): only do this once link actually
|
// TODO(roasbeef): only do this once link actually
|
||||||
// fully settles?
|
// fully settles?
|
||||||
localHTLC := packet.incomingChanID == sourceHop
|
localHTLC := packet.incomingChanID == hop.Source
|
||||||
if !localHTLC {
|
if !localHTLC {
|
||||||
s.fwdEventMtx.Lock()
|
s.fwdEventMtx.Lock()
|
||||||
s.pendingFwdingEvents = append(
|
s.pendingFwdingEvents = append(
|
||||||
@ -1241,7 +1242,7 @@ func (s *Switch) handlePacketForward(packet *htlcPacket) error {
|
|||||||
|
|
||||||
// A blank IncomingChanID in a circuit indicates that it is a pending
|
// A blank IncomingChanID in a circuit indicates that it is a pending
|
||||||
// user-initiated payment.
|
// user-initiated payment.
|
||||||
if packet.incomingChanID == sourceHop {
|
if packet.incomingChanID == hop.Source {
|
||||||
return s.handleLocalDispatch(packet)
|
return s.handleLocalDispatch(packet)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1798,7 +1799,7 @@ func (s *Switch) reforwardResponses() error {
|
|||||||
shortChanID := openChannel.ShortChanID()
|
shortChanID := openChannel.ShortChanID()
|
||||||
|
|
||||||
// Locally-initiated payments never need reforwarding.
|
// Locally-initiated payments never need reforwarding.
|
||||||
if shortChanID == sourceHop {
|
if shortChanID == hop.Source {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1994,7 +1995,7 @@ func (s *Switch) AddLink(link ChannelLink) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
shortChanID := link.ShortChanID()
|
shortChanID := link.ShortChanID()
|
||||||
if shortChanID == sourceHop {
|
if shortChanID == hop.Source {
|
||||||
log.Infof("Adding pending link chan_id=%v, short_chan_id=%v",
|
log.Infof("Adding pending link chan_id=%v, short_chan_id=%v",
|
||||||
chanID, shortChanID)
|
chanID, shortChanID)
|
||||||
|
|
||||||
@ -2157,7 +2158,7 @@ func (s *Switch) UpdateShortChanID(chanID lnwire.ChannelID) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Reject any blank short channel ids.
|
// Reject any blank short channel ids.
|
||||||
if shortChanID == sourceHop {
|
if shortChanID == hop.Source {
|
||||||
return fmt.Errorf("refusing trivial short_chan_id for chan_id=%v"+
|
return fmt.Errorf("refusing trivial short_chan_id for chan_id=%v"+
|
||||||
"live link", chanID)
|
"live link", chanID)
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
"github.com/go-errors/errors"
|
"github.com/go-errors/errors"
|
||||||
"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/hop"
|
||||||
"github.com/lightningnetwork/lnd/input"
|
"github.com/lightningnetwork/lnd/input"
|
||||||
"github.com/lightningnetwork/lnd/keychain"
|
"github.com/lightningnetwork/lnd/keychain"
|
||||||
"github.com/lightningnetwork/lnd/lnpeer"
|
"github.com/lightningnetwork/lnd/lnpeer"
|
||||||
@ -596,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")
|
||||||
@ -635,16 +638,17 @@ 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.
|
||||||
nextHop := exitHop
|
nextHop := hop.Exit
|
||||||
if i != len(path)-1 {
|
if i != len(path)-1 {
|
||||||
nextHop = path[i+1].channel.ShortChanID()
|
nextHop = path[i+1].channel.ShortChanID()
|
||||||
}
|
}
|
||||||
@ -679,8 +683,8 @@ func generateHops(payAmt lnwire.MilliSatoshi, startingHeight uint32,
|
|||||||
amount = runningAmt - fee
|
amount = runningAmt - fee
|
||||||
}
|
}
|
||||||
|
|
||||||
hops[i] = ForwardingInfo{
|
hops[i] = hop.ForwardingInfo{
|
||||||
Network: BitcoinHop,
|
Network: hop.BitcoinNetwork,
|
||||||
NextHop: nextHop,
|
NextHop: nextHop,
|
||||||
AmountToForward: amount,
|
AmountToForward: amount,
|
||||||
OutgoingCTLV: timeLock,
|
OutgoingCTLV: timeLock,
|
||||||
@ -731,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 {
|
||||||
|
|
||||||
@ -765,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) {
|
||||||
|
|
||||||
@ -1246,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