htlcswitch+hop: move ForwardingInfo to hop.ForwaringInfo

This commit is contained in:
Conner Fromknecht 2019-08-30 14:11:20 -07:00
parent 83d2112e8b
commit fc0e4be4d8
No known key found for this signature in database
GPG Key ID: E7D737B67FA592C7
7 changed files with 66 additions and 54 deletions

@ -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
)
// 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
// 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
@ -62,7 +35,7 @@ type HopIterator interface {
// Additionally, the information encoded within the returned
// ForwardingInfo is to be used by each hop to authenticate the
// information given to it by the prior hop.
ForwardingInstructions() (ForwardingInfo, error)
ForwardingInstructions() (hop.ForwardingInfo, error)
// ExtraOnionBlob returns the additional EOB data (if available).
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.
//
// NOTE: Part of the HopIterator interface.
func (r *sphinxHopIterator) ForwardingInstructions() (ForwardingInfo, error) {
func (r *sphinxHopIterator) ForwardingInstructions() (
hop.ForwardingInfo, error) {
var (
nextHop lnwire.ShortChannelID
amt uint64
@ -154,24 +129,25 @@ func (r *sphinxHopIterator) ForwardingInstructions() (ForwardingInfo, error) {
record.NewNextHopIDRecord(&cid),
)
if err != nil {
return ForwardingInfo{}, err
return hop.ForwardingInfo{}, err
}
err = tlvStream.Decode(bytes.NewReader(
r.processedPacket.Payload.Payload,
))
if err != nil {
return ForwardingInfo{}, err
return hop.ForwardingInfo{}, err
}
nextHop = lnwire.NewShortChanIDFromInt(cid)
default:
return ForwardingInfo{}, fmt.Errorf("unknown sphinx payload "+
"type: %v", r.processedPacket.Payload.Type)
return hop.ForwardingInfo{}, fmt.Errorf("unknown "+
"sphinx payload type: %v",
r.processedPacket.Payload.Type)
}
return ForwardingInfo{
return hop.ForwardingInfo{
Network: hop.BitcoinNetwork,
NextHop: nextHop,
AmountToForward: lnwire.MilliSatoshi(amt),

@ -7,6 +7,7 @@ import (
"github.com/davecgh/go-spew/spew"
sphinx "github.com/lightningnetwork/lightning-onion"
"github.com/lightningnetwork/lnd/htlcswitch/hop"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/record"
"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
// extract each type, no matter the payload type.
nextAddrInt := binary.BigEndian.Uint64(hopData.NextAddress[:])
expectedFwdInfo := ForwardingInfo{
expectedFwdInfo := hop.ForwardingInfo{
NextHop: lnwire.NewShortChanIDFromInt(nextAddrInt),
AmountToForward: lnwire.MilliSatoshi(hopData.ForwardAmount),
OutgoingCTLV: hopData.OutgoingCltv,
@ -53,7 +54,7 @@ func TestSphinxHopIteratorForwardingInstructions(t *testing.T) {
var testCases = []struct {
sphinxPacket *sphinx.ProcessedPacket
expectedFwdInfo ForwardingInfo
expectedFwdInfo hop.ForwardingInfo
}{
// A regular legacy payload that signals more hops.
{

@ -16,6 +16,7 @@ import (
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/contractcourt"
"github.com/lightningnetwork/lnd/htlcswitch/hodl"
"github.com/lightningnetwork/lnd/htlcswitch/hop"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/invoices"
"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
// returns a boolean indicating whether the commitment tx needs an update.
func (l *channelLink) processExitHop(pd *lnwallet.PaymentDescriptor,
obfuscator ErrorEncrypter, fwdInfo ForwardingInfo,
obfuscator ErrorEncrypter, fwdInfo hop.ForwardingInfo,
heightNow uint32, eob []byte) (bool, error) {
// 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)
htlcExpiry := testStartingHeight + testInvoiceCltvExpiry
hops := []ForwardingInfo{
hops := []hop.ForwardingInfo{
{
Network: hop.BitcoinNetwork,
NextHop: exitHop,

@ -269,14 +269,16 @@ func (s *mockServer) QuitSignal() <-chan struct{} {
// 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.
type mockHopIterator struct {
hops []ForwardingInfo
hops []hop.ForwardingInfo
}
func newMockHopIterator(hops ...ForwardingInfo) HopIterator {
func newMockHopIterator(hops ...hop.ForwardingInfo) HopIterator {
return &mockHopIterator{hops: hops}
}
func (r *mockHopIterator) ForwardingInstructions() (ForwardingInfo, error) {
func (r *mockHopIterator) ForwardingInstructions() (
hop.ForwardingInfo, error) {
h := r.hops[0]
r.hops = r.hops[1:]
return h, nil
@ -301,7 +303,7 @@ func (r *mockHopIterator) EncodeNextHop(w io.Writer) error {
}
for _, hop := range r.hops {
if err := hop.encode(w); err != nil {
if err := encodeFwdInfo(w, &hop); err != nil {
return err
}
}
@ -309,7 +311,7 @@ func (r *mockHopIterator) EncodeNextHop(w io.Writer) error {
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 {
return err
}
@ -430,10 +432,10 @@ func (p *mockIteratorDecoder) DecodeHopIterator(r io.Reader, rHash []byte,
}
hopLength := binary.BigEndian.Uint32(b[:])
hops := make([]ForwardingInfo, hopLength)
hops := make([]hop.ForwardingInfo, hopLength)
for i := uint32(0); i < hopLength; i++ {
f := &ForwardingInfo{}
if err := f.decode(r); err != nil {
f := &hop.ForwardingInfo{}
if err := decodeFwdInfo(r, f); err != nil {
return nil, lnwire.CodeTemporaryChannelFailure
}
@ -481,7 +483,7 @@ func (p *mockIteratorDecoder) DecodeHopIterators(id []byte,
return resps, nil
}
func (f *ForwardingInfo) decode(r io.Reader) error {
func decodeFwdInfo(r io.Reader, f *hop.ForwardingInfo) error {
var net [1]byte
if _, err := r.Read(net[:]); err != nil {
return err

@ -597,7 +597,9 @@ func generatePayment(invoiceAmt, htlcAmt lnwire.MilliSatoshi, timelock uint32,
}
// 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
if len(hops) == 0 {
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
// the specified path.
func generateHops(payAmt lnwire.MilliSatoshi, startingHeight uint32,
path ...*channelLink) (lnwire.MilliSatoshi, uint32, []ForwardingInfo) {
path ...*channelLink) (lnwire.MilliSatoshi, uint32,
[]hop.ForwardingInfo) {
totalTimelock := startingHeight
runningAmt := payAmt
hops := make([]ForwardingInfo, len(path))
hops := make([]hop.ForwardingInfo, len(path))
for i := len(path) - 1; i >= 0; i-- {
// If this is the last hop, then the next hop is the special
// "exit node". Otherwise, we look to the "prior" hop.
@ -680,7 +683,7 @@ func generateHops(payAmt lnwire.MilliSatoshi, startingHeight uint32,
amount = runningAmt - fee
}
hops[i] = ForwardingInfo{
hops[i] = hop.ForwardingInfo{
Network: hop.BitcoinNetwork,
NextHop: nextHop,
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 some another peer through the Bob
func makePayment(sendingPeer, receivingPeer lnpeer.Peer,
firstHop lnwire.ShortChannelID, hops []ForwardingInfo,
firstHop lnwire.ShortChannelID, hops []hop.ForwardingInfo,
invoiceAmt, htlcAmt lnwire.MilliSatoshi,
timelock uint32) *paymentResponse {
@ -766,7 +769,7 @@ func makePayment(sendingPeer, receivingPeer lnpeer.Peer,
// preparePayment creates an invoice at the receivingPeer and returns a function
// that, when called, launches the payment from the sendingPeer.
func preparePayment(sendingPeer, receivingPeer lnpeer.Peer,
firstHop lnwire.ShortChannelID, hops []ForwardingInfo,
firstHop lnwire.ShortChannelID, hops []hop.ForwardingInfo,
invoiceAmt, htlcAmt lnwire.MilliSatoshi,
timelock uint32) (*channeldb.Invoice, func() error, error) {
@ -1247,7 +1250,7 @@ func (n *twoHopNetwork) stop() {
}
func (n *twoHopNetwork) makeHoldPayment(sendingPeer, receivingPeer lnpeer.Peer,
firstHop lnwire.ShortChannelID, hops []ForwardingInfo,
firstHop lnwire.ShortChannelID, hops []hop.ForwardingInfo,
invoiceAmt, htlcAmt lnwire.MilliSatoshi,
timelock uint32, preimage lntypes.Preimage) chan error {