lnwire: prep wire messages for TLV extensions

Messages:
- UpdateFulfillHTLC
- UpdateFee
- UpdateFailMalformedHTLC
- UpdateFailHTLC
- UpdateAddHTLC
- Shutdown
- RevokeAndAck
- ReplyShortChanIDsEnd
- ReplyChannelRange
- QueryShortChanIDs
- QueryChannelRange
- NodeAnnouncement
- Init
- GossipTimestampRange
- FundingSigned
- FundingLocked
- FundingCreated
- CommitSig
- ClosingSigned
- ChannelUpdate
- ChannelReestablish
- ChannelAnnouncement
- AnnounceSignatures

lnwire: update quickcheck tests, use constant for Error

multi: update unit tests to pass deep equal assertions with messages

In this commit, we update a series of unit tests in the code base to now
pass due to the new wire message encode/decode logic. In many instances,
we'll now manually set the extra bytes to an empty byte slice to avoid
comparisons that fail due to one message having an empty byte slice and
the other having a nil pointer.
This commit is contained in:
Olaoluwa Osuntokun 2020-01-27 17:25:36 -08:00 committed by Johan T. Halseth
parent a603ac4938
commit 9a6bb19770
No known key found for this signature in database
GPG Key ID: 15BAADA29DA20D26
32 changed files with 278 additions and 231 deletions

View File

@ -607,7 +607,8 @@ func TestChannelStateTransition(t *testing.T) {
{ {
LogIndex: 2, LogIndex: 2,
UpdateMsg: &lnwire.UpdateAddHTLC{ UpdateMsg: &lnwire.UpdateAddHTLC{
ChanID: lnwire.ChannelID{1, 2, 3}, ChanID: lnwire.ChannelID{1, 2, 3},
ExtraData: make([]byte, 0),
}, },
}, },
} }
@ -628,7 +629,9 @@ func TestChannelStateTransition(t *testing.T) {
if !reflect.DeepEqual( if !reflect.DeepEqual(
dbUnsignedAckedUpdates[0], unsignedAckedUpdates[0], dbUnsignedAckedUpdates[0], unsignedAckedUpdates[0],
) { ) {
t.Fatalf("unexpected update") t.Fatalf("unexpected update: expected %v, got %v",
spew.Sdump(unsignedAckedUpdates[0]),
spew.Sdump(dbUnsignedAckedUpdates))
} }
// The balances, new update, the HTLCs and the changes to the fake // The balances, new update, the HTLCs and the changes to the fake
@ -670,22 +673,25 @@ func TestChannelStateTransition(t *testing.T) {
wireSig, wireSig,
wireSig, wireSig,
}, },
ExtraData: make([]byte, 0),
}, },
LogUpdates: []LogUpdate{ LogUpdates: []LogUpdate{
{ {
LogIndex: 1, LogIndex: 1,
UpdateMsg: &lnwire.UpdateAddHTLC{ UpdateMsg: &lnwire.UpdateAddHTLC{
ID: 1, ID: 1,
Amount: lnwire.NewMSatFromSatoshis(100), Amount: lnwire.NewMSatFromSatoshis(100),
Expiry: 25, Expiry: 25,
ExtraData: make([]byte, 0),
}, },
}, },
{ {
LogIndex: 2, LogIndex: 2,
UpdateMsg: &lnwire.UpdateAddHTLC{ UpdateMsg: &lnwire.UpdateAddHTLC{
ID: 2, ID: 2,
Amount: lnwire.NewMSatFromSatoshis(200), Amount: lnwire.NewMSatFromSatoshis(200),
Expiry: 50, Expiry: 50,
ExtraData: make([]byte, 0),
}, },
}, },
}, },

View File

@ -5,6 +5,7 @@ import (
"reflect" "reflect"
"github.com/davecgh/go-spew/spew"
"github.com/go-errors/errors" "github.com/go-errors/errors"
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
) )
@ -23,6 +24,7 @@ func TestWaitingProofStore(t *testing.T) {
proof1 := NewWaitingProof(true, &lnwire.AnnounceSignatures{ proof1 := NewWaitingProof(true, &lnwire.AnnounceSignatures{
NodeSignature: wireSig, NodeSignature: wireSig,
BitcoinSignature: wireSig, BitcoinSignature: wireSig,
ExtraOpaqueData: make([]byte, 0),
}) })
store, err := NewWaitingProofStore(db) store, err := NewWaitingProofStore(db)
@ -40,7 +42,8 @@ func TestWaitingProofStore(t *testing.T) {
t.Fatalf("unable retrieve proof from storage: %v", err) t.Fatalf("unable retrieve proof from storage: %v", err)
} }
if !reflect.DeepEqual(proof1, proof2) { if !reflect.DeepEqual(proof1, proof2) {
t.Fatal("wrong proof retrieved") t.Fatalf("wrong proof retrieved: expected %v, got %v",
spew.Sdump(proof1), spew.Sdump(proof2))
} }
if _, err := store.Get(proof1.OppositeKey()); err != ErrWaitingProofNotFound { if _, err := store.Get(proof1.OppositeKey()); err != ErrWaitingProofNotFound {

View File

@ -64,13 +64,15 @@ func randCompressedPubKey(t *testing.T) [33]byte {
func randAnnounceSignatures() *lnwire.AnnounceSignatures { func randAnnounceSignatures() *lnwire.AnnounceSignatures {
return &lnwire.AnnounceSignatures{ return &lnwire.AnnounceSignatures{
ShortChannelID: lnwire.NewShortChanIDFromInt(rand.Uint64()), ShortChannelID: lnwire.NewShortChanIDFromInt(rand.Uint64()),
ExtraOpaqueData: make([]byte, 0),
} }
} }
func randChannelUpdate() *lnwire.ChannelUpdate { func randChannelUpdate() *lnwire.ChannelUpdate {
return &lnwire.ChannelUpdate{ return &lnwire.ChannelUpdate{
ShortChannelID: lnwire.NewShortChanIDFromInt(rand.Uint64()), ShortChannelID: lnwire.NewShortChanIDFromInt(rand.Uint64()),
ExtraOpaqueData: make([]byte, 0),
} }
} }

View File

@ -39,18 +39,21 @@ func TestNetworkResultSerialization(t *testing.T) {
ChanID: chanID, ChanID: chanID,
ID: 2, ID: 2,
PaymentPreimage: preimage, PaymentPreimage: preimage,
ExtraData: make([]byte, 0),
} }
fail := &lnwire.UpdateFailHTLC{ fail := &lnwire.UpdateFailHTLC{
ChanID: chanID, ChanID: chanID,
ID: 1, ID: 1,
Reason: []byte{}, Reason: []byte{},
ExtraData: make([]byte, 0),
} }
fail2 := &lnwire.UpdateFailHTLC{ fail2 := &lnwire.UpdateFailHTLC{
ChanID: chanID, ChanID: chanID,
ID: 1, ID: 1,
Reason: reason[:], Reason: reason[:],
ExtraData: make([]byte, 0),
} }
testCases := []*networkResult{ testCases := []*networkResult{

View File

@ -3176,6 +3176,7 @@ func TestChanSyncOweCommitment(t *testing.T) {
Amount: htlcAmt, Amount: htlcAmt,
Expiry: uint32(10), Expiry: uint32(10),
OnionBlob: fakeOnionBlob, OnionBlob: fakeOnionBlob,
ExtraData: make([]byte, 0),
} }
htlcIndex, err := bobChannel.AddHTLC(h, nil) htlcIndex, err := bobChannel.AddHTLC(h, nil)
@ -3220,6 +3221,7 @@ func TestChanSyncOweCommitment(t *testing.T) {
Amount: htlcAmt, Amount: htlcAmt,
Expiry: uint32(10), Expiry: uint32(10),
OnionBlob: fakeOnionBlob, OnionBlob: fakeOnionBlob,
ExtraData: make([]byte, 0),
} }
aliceHtlcIndex, err := aliceChannel.AddHTLC(aliceHtlc, nil) aliceHtlcIndex, err := aliceChannel.AddHTLC(aliceHtlc, nil)
if err != nil { if err != nil {

View File

@ -2,7 +2,6 @@ package lnwire
import ( import (
"io" "io"
"io/ioutil"
) )
// AnnounceSignatures is a direct message between two endpoints of a // AnnounceSignatures is a direct message between two endpoints of a
@ -40,7 +39,7 @@ type AnnounceSignatures struct {
// properly validate the set of signatures that cover these new fields, // properly validate the set of signatures that cover these new fields,
// and ensure we're able to make upgrades to the network in a forwards // and ensure we're able to make upgrades to the network in a forwards
// compatible manner. // compatible manner.
ExtraOpaqueData []byte ExtraOpaqueData ExtraOpaqueData
} }
// A compile time check to ensure AnnounceSignatures implements the // A compile time check to ensure AnnounceSignatures implements the
@ -52,29 +51,13 @@ var _ Message = (*AnnounceSignatures)(nil)
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (a *AnnounceSignatures) Decode(r io.Reader, pver uint32) error { func (a *AnnounceSignatures) Decode(r io.Reader, pver uint32) error {
err := ReadElements(r, return ReadElements(r,
&a.ChannelID, &a.ChannelID,
&a.ShortChannelID, &a.ShortChannelID,
&a.NodeSignature, &a.NodeSignature,
&a.BitcoinSignature, &a.BitcoinSignature,
&a.ExtraOpaqueData,
) )
if err != nil {
return err
}
// Now that we've read out all the fields that we explicitly know of,
// we'll collect the remainder into the ExtraOpaqueData field. If there
// aren't any bytes, then we'll snip off the slice to avoid carrying
// around excess capacity.
a.ExtraOpaqueData, err = ioutil.ReadAll(r)
if err != nil {
return err
}
if len(a.ExtraOpaqueData) == 0 {
a.ExtraOpaqueData = nil
}
return nil
} }
// Encode serializes the target AnnounceSignatures into the passed io.Writer // Encode serializes the target AnnounceSignatures into the passed io.Writer
@ -104,5 +87,5 @@ func (a *AnnounceSignatures) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (a *AnnounceSignatures) MaxPayloadLength(pver uint32) uint32 { func (a *AnnounceSignatures) MaxPayloadLength(pver uint32) uint32 {
return 65533 return MaxMsgBody
} }

View File

@ -3,7 +3,6 @@ package lnwire
import ( import (
"bytes" "bytes"
"io" "io"
"io/ioutil"
"github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/chaincfg/chainhash"
) )
@ -56,7 +55,7 @@ type ChannelAnnouncement struct {
// properly validate the set of signatures that cover these new fields, // properly validate the set of signatures that cover these new fields,
// and ensure we're able to make upgrades to the network in a forwards // and ensure we're able to make upgrades to the network in a forwards
// compatible manner. // compatible manner.
ExtraOpaqueData []byte ExtraOpaqueData ExtraOpaqueData
} }
// A compile time check to ensure ChannelAnnouncement implements the // A compile time check to ensure ChannelAnnouncement implements the
@ -68,7 +67,7 @@ var _ Message = (*ChannelAnnouncement)(nil)
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (a *ChannelAnnouncement) Decode(r io.Reader, pver uint32) error { func (a *ChannelAnnouncement) Decode(r io.Reader, pver uint32) error {
err := ReadElements(r, return ReadElements(r,
&a.NodeSig1, &a.NodeSig1,
&a.NodeSig2, &a.NodeSig2,
&a.BitcoinSig1, &a.BitcoinSig1,
@ -80,24 +79,8 @@ func (a *ChannelAnnouncement) Decode(r io.Reader, pver uint32) error {
&a.NodeID2, &a.NodeID2,
&a.BitcoinKey1, &a.BitcoinKey1,
&a.BitcoinKey2, &a.BitcoinKey2,
&a.ExtraOpaqueData,
) )
if err != nil {
return err
}
// Now that we've read out all the fields that we explicitly know of,
// we'll collect the remainder into the ExtraOpaqueData field. If there
// aren't any bytes, then we'll snip off the slice to avoid carrying
// around excess capacity.
a.ExtraOpaqueData, err = ioutil.ReadAll(r)
if err != nil {
return err
}
if len(a.ExtraOpaqueData) == 0 {
a.ExtraOpaqueData = nil
}
return nil
} }
// Encode serializes the target ChannelAnnouncement into the passed io.Writer // Encode serializes the target ChannelAnnouncement into the passed io.Writer
@ -134,7 +117,7 @@ func (a *ChannelAnnouncement) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (a *ChannelAnnouncement) MaxPayloadLength(pver uint32) uint32 { func (a *ChannelAnnouncement) MaxPayloadLength(pver uint32) uint32 {
return 65533 return MaxMsgBody
} }
// DataToSign is used to retrieve part of the announcement message which should // DataToSign is used to retrieve part of the announcement message which should

View File

@ -60,6 +60,11 @@ type ChannelReestablish struct {
// LocalUnrevokedCommitPoint is the commitment point used in the // LocalUnrevokedCommitPoint is the commitment point used in the
// current un-revoked commitment transaction of the sending party. // current un-revoked commitment transaction of the sending party.
LocalUnrevokedCommitPoint *btcec.PublicKey LocalUnrevokedCommitPoint *btcec.PublicKey
// ExtraData is the set of data that was appended to this message to
// fill out the full maximum transport message size. These fields can
// be used to specify optional data such as custom TLV fields.
ExtraData ExtraOpaqueData
} }
// A compile time check to ensure ChannelReestablish implements the // A compile time check to ensure ChannelReestablish implements the
@ -83,12 +88,20 @@ func (a *ChannelReestablish) Encode(w io.Writer, pver uint32) error {
// If the commit point wasn't sent, then we won't write out any of the // If the commit point wasn't sent, then we won't write out any of the
// remaining fields as they're optional. // remaining fields as they're optional.
if a.LocalUnrevokedCommitPoint == nil { if a.LocalUnrevokedCommitPoint == nil {
return nil // However, we'll still write out the extra data if it's
// present.
//
// NOTE: This is here primarily for the quickcheck tests, in
// practice, we'll always populate this field.
return WriteElements(w, a.ExtraData)
} }
// Otherwise, we'll write out the remaining elements. // Otherwise, we'll write out the remaining elements.
return WriteElements(w, a.LastRemoteCommitSecret[:], return WriteElements(w,
a.LocalUnrevokedCommitPoint) a.LastRemoteCommitSecret[:],
a.LocalUnrevokedCommitPoint,
a.ExtraData,
)
} }
// Decode deserializes a serialized ChannelReestablish stored in the passed // Decode deserializes a serialized ChannelReestablish stored in the passed
@ -118,6 +131,9 @@ func (a *ChannelReestablish) Decode(r io.Reader, pver uint32) error {
var buf [32]byte var buf [32]byte
_, err = io.ReadFull(r, buf[:32]) _, err = io.ReadFull(r, buf[:32])
if err == io.EOF { if err == io.EOF {
// If there aren't any more bytes, then we'll emplace an empty
// extra data to make our quickcheck tests happy.
a.ExtraData = make([]byte, 0)
return nil return nil
} else if err != nil { } else if err != nil {
return err return err
@ -129,7 +145,11 @@ func (a *ChannelReestablish) Decode(r io.Reader, pver uint32) error {
// We'll conclude by parsing out the commitment point. We don't check // We'll conclude by parsing out the commitment point. We don't check
// the error in this case, as it has included the commit secret, then // the error in this case, as it has included the commit secret, then
// they MUST also include the commit point. // they MUST also include the commit point.
return ReadElement(r, &a.LocalUnrevokedCommitPoint) if err = ReadElement(r, &a.LocalUnrevokedCommitPoint); err != nil {
return err
}
return a.ExtraData.Decode(r)
} }
// MsgType returns the integer uniquely identifying this message type on the // MsgType returns the integer uniquely identifying this message type on the
@ -145,22 +165,5 @@ func (a *ChannelReestablish) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (a *ChannelReestablish) MaxPayloadLength(pver uint32) uint32 { func (a *ChannelReestablish) MaxPayloadLength(pver uint32) uint32 {
var length uint32 return MaxMsgBody
// ChanID - 32 bytes
length += 32
// NextLocalCommitHeight - 8 bytes
length += 8
// RemoteCommitTailHeight - 8 bytes
length += 8
// LastRemoteCommitSecret - 32 bytes
length += 32
// LocalUnrevokedCommitPoint - 33 bytes
length += 33
return length
} }

View File

@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/chaincfg/chainhash"
) )
@ -115,13 +114,10 @@ type ChannelUpdate struct {
// HtlcMaximumMsat is the maximum HTLC value which will be accepted. // HtlcMaximumMsat is the maximum HTLC value which will be accepted.
HtlcMaximumMsat MilliSatoshi HtlcMaximumMsat MilliSatoshi
// ExtraOpaqueData is the set of data that was appended to this // ExtraData is the set of data that was appended to this message to
// message, some of which we may not actually know how to iterate or // fill out the full maximum transport message size. These fields can
// parse. By holding onto this data, we ensure that we're able to // be used to specify optional data such as custom TLV fields.
// properly validate the set of signatures that cover these new fields, ExtraOpaqueData ExtraOpaqueData
// and ensure we're able to make upgrades to the network in a forwards
// compatible manner.
ExtraOpaqueData []byte
} }
// A compile time check to ensure ChannelUpdate implements the lnwire.Message // A compile time check to ensure ChannelUpdate implements the lnwire.Message
@ -156,19 +152,7 @@ func (a *ChannelUpdate) Decode(r io.Reader, pver uint32) error {
} }
} }
// Now that we've read out all the fields that we explicitly know of, return a.ExtraOpaqueData.Decode(r)
// we'll collect the remainder into the ExtraOpaqueData field. If there
// aren't any bytes, then we'll snip off the slice to avoid carrying
// around excess capacity.
a.ExtraOpaqueData, err = ioutil.ReadAll(r)
if err != nil {
return err
}
if len(a.ExtraOpaqueData) == 0 {
a.ExtraOpaqueData = nil
}
return nil
} }
// Encode serializes the target ChannelUpdate into the passed io.Writer // Encode serializes the target ChannelUpdate into the passed io.Writer
@ -201,7 +185,7 @@ func (a *ChannelUpdate) Encode(w io.Writer, pver uint32) error {
} }
// Finally, append any extra opaque data. // Finally, append any extra opaque data.
return WriteElements(w, a.ExtraOpaqueData) return a.ExtraOpaqueData.Encode(w)
} }
// MsgType returns the integer uniquely identifying this message type on the // MsgType returns the integer uniquely identifying this message type on the
@ -217,7 +201,7 @@ func (a *ChannelUpdate) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (a *ChannelUpdate) MaxPayloadLength(pver uint32) uint32 { func (a *ChannelUpdate) MaxPayloadLength(pver uint32) uint32 {
return 65533 return MaxMsgBody
} }
// DataToSign is used to retrieve part of the announcement message which should // DataToSign is used to retrieve part of the announcement message which should
@ -250,7 +234,7 @@ func (a *ChannelUpdate) DataToSign() ([]byte, error) {
} }
// Finally, append any extra opaque data. // Finally, append any extra opaque data.
if err := WriteElements(&w, a.ExtraOpaqueData); err != nil { if err := a.ExtraOpaqueData.Encode(&w); err != nil {
return nil, err return nil, err
} }

View File

@ -27,6 +27,11 @@ type ClosingSigned struct {
// Signature is for the proposed channel close transaction. // Signature is for the proposed channel close transaction.
Signature Sig Signature Sig
// ExtraData is the set of data that was appended to this message to
// fill out the full maximum transport message size. These fields can
// be used to specify optional data such as custom TLV fields.
ExtraData ExtraOpaqueData
} }
// NewClosingSigned creates a new empty ClosingSigned message. // NewClosingSigned creates a new empty ClosingSigned message.
@ -49,7 +54,9 @@ var _ Message = (*ClosingSigned)(nil)
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (c *ClosingSigned) Decode(r io.Reader, pver uint32) error { func (c *ClosingSigned) Decode(r io.Reader, pver uint32) error {
return ReadElements(r, &c.ChannelID, &c.FeeSatoshis, &c.Signature) return ReadElements(
r, &c.ChannelID, &c.FeeSatoshis, &c.Signature, &c.ExtraData,
)
} }
// Encode serializes the target ClosingSigned into the passed io.Writer // Encode serializes the target ClosingSigned into the passed io.Writer
@ -57,7 +64,9 @@ func (c *ClosingSigned) Decode(r io.Reader, pver uint32) error {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (c *ClosingSigned) Encode(w io.Writer, pver uint32) error { func (c *ClosingSigned) Encode(w io.Writer, pver uint32) error {
return WriteElements(w, c.ChannelID, c.FeeSatoshis, c.Signature) return WriteElements(
w, c.ChannelID, c.FeeSatoshis, c.Signature, c.ExtraData,
)
} }
// MsgType returns the integer uniquely identifying this message type on the // MsgType returns the integer uniquely identifying this message type on the
@ -73,16 +82,5 @@ func (c *ClosingSigned) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (c *ClosingSigned) MaxPayloadLength(uint32) uint32 { func (c *ClosingSigned) MaxPayloadLength(uint32) uint32 {
var length uint32 return MaxMsgBody
// ChannelID - 32 bytes
length += 32
// FeeSatoshis - 8 bytes
length += 8
// Signature - 64 bytes
length += 64
return length
} }

View File

@ -34,11 +34,18 @@ type CommitSig struct {
// should be signed, for each incoming HTLC the HTLC timeout // should be signed, for each incoming HTLC the HTLC timeout
// transaction should be signed. // transaction should be signed.
HtlcSigs []Sig HtlcSigs []Sig
// ExtraData is the set of data that was appended to this message to
// fill out the full maximum transport message size. These fields can
// be used to specify optional data such as custom TLV fields.
ExtraData ExtraOpaqueData
} }
// NewCommitSig creates a new empty CommitSig message. // NewCommitSig creates a new empty CommitSig message.
func NewCommitSig() *CommitSig { func NewCommitSig() *CommitSig {
return &CommitSig{} return &CommitSig{
ExtraData: make([]byte, 0),
}
} }
// A compile time check to ensure CommitSig implements the lnwire.Message // A compile time check to ensure CommitSig implements the lnwire.Message
@ -54,6 +61,7 @@ func (c *CommitSig) Decode(r io.Reader, pver uint32) error {
&c.ChanID, &c.ChanID,
&c.CommitSig, &c.CommitSig,
&c.HtlcSigs, &c.HtlcSigs,
&c.ExtraData,
) )
} }
@ -66,6 +74,7 @@ func (c *CommitSig) Encode(w io.Writer, pver uint32) error {
c.ChanID, c.ChanID,
c.CommitSig, c.CommitSig,
c.HtlcSigs, c.HtlcSigs,
c.ExtraData,
) )
} }
@ -82,8 +91,7 @@ func (c *CommitSig) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (c *CommitSig) MaxPayloadLength(uint32) uint32 { func (c *CommitSig) MaxPayloadLength(uint32) uint32 {
// 32 + 64 + 2 + max_allowed_htlcs return MaxMsgBody
return MaxMessagePayload
} }
// TargetChanID returns the channel id of the link for which this message is // TargetChanID returns the channel id of the link for which this message is

View File

@ -123,8 +123,7 @@ func (c *Error) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (c *Error) MaxPayloadLength(uint32) uint32 { func (c *Error) MaxPayloadLength(uint32) uint32 {
// 32 + 2 + 65501 return MaxMsgBody
return MaxMessagePayload
} }
// isASCII is a helper method that checks whether all bytes in `data` would be // isASCII is a helper method that checks whether all bytes in `data` would be

View File

@ -24,6 +24,11 @@ type FundingCreated struct {
// CommitSig is Alice's signature from Bob's version of the commitment // CommitSig is Alice's signature from Bob's version of the commitment
// transaction. // transaction.
CommitSig Sig CommitSig Sig
// ExtraData is the set of data that was appended to this message to
// fill out the full maximum transport message size. These fields can
// be used to specify optional data such as custom TLV fields.
ExtraData ExtraOpaqueData
} }
// A compile time check to ensure FundingCreated implements the lnwire.Message // A compile time check to ensure FundingCreated implements the lnwire.Message
@ -36,7 +41,10 @@ var _ Message = (*FundingCreated)(nil)
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (f *FundingCreated) Encode(w io.Writer, pver uint32) error { func (f *FundingCreated) Encode(w io.Writer, pver uint32) error {
return WriteElements(w, f.PendingChannelID[:], f.FundingPoint, f.CommitSig) return WriteElements(
w, f.PendingChannelID[:], f.FundingPoint, f.CommitSig,
f.ExtraData,
)
} }
// Decode deserializes the serialized FundingCreated stored in the passed // Decode deserializes the serialized FundingCreated stored in the passed
@ -45,7 +53,10 @@ func (f *FundingCreated) Encode(w io.Writer, pver uint32) error {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (f *FundingCreated) Decode(r io.Reader, pver uint32) error { func (f *FundingCreated) Decode(r io.Reader, pver uint32) error {
return ReadElements(r, f.PendingChannelID[:], &f.FundingPoint, &f.CommitSig) return ReadElements(
r, f.PendingChannelID[:], &f.FundingPoint, &f.CommitSig,
&f.ExtraData,
)
} }
// MsgType returns the uint32 code which uniquely identifies this message as a // MsgType returns the uint32 code which uniquely identifies this message as a
@ -61,6 +72,5 @@ func (f *FundingCreated) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (f *FundingCreated) MaxPayloadLength(uint32) uint32 { func (f *FundingCreated) MaxPayloadLength(uint32) uint32 {
// 32 + 32 + 2 + 64 return MaxMsgBody
return 130
} }

View File

@ -19,6 +19,11 @@ type FundingLocked struct {
// NextPerCommitmentPoint is the secret that can be used to revoke the // NextPerCommitmentPoint is the secret that can be used to revoke the
// next commitment transaction for the channel. // next commitment transaction for the channel.
NextPerCommitmentPoint *btcec.PublicKey NextPerCommitmentPoint *btcec.PublicKey
// ExtraData is the set of data that was appended to this message to
// fill out the full maximum transport message size. These fields can
// be used to specify optional data such as custom TLV fields.
ExtraData ExtraOpaqueData
} }
// NewFundingLocked creates a new FundingLocked message, populating it with the // NewFundingLocked creates a new FundingLocked message, populating it with the
@ -27,6 +32,7 @@ func NewFundingLocked(cid ChannelID, npcp *btcec.PublicKey) *FundingLocked {
return &FundingLocked{ return &FundingLocked{
ChanID: cid, ChanID: cid,
NextPerCommitmentPoint: npcp, NextPerCommitmentPoint: npcp,
ExtraData: make([]byte, 0),
} }
} }
@ -42,7 +48,9 @@ var _ Message = (*FundingLocked)(nil)
func (c *FundingLocked) Decode(r io.Reader, pver uint32) error { func (c *FundingLocked) Decode(r io.Reader, pver uint32) error {
return ReadElements(r, return ReadElements(r,
&c.ChanID, &c.ChanID,
&c.NextPerCommitmentPoint) &c.NextPerCommitmentPoint,
&c.ExtraData,
)
} }
// Encode serializes the target FundingLocked message into the passed io.Writer // Encode serializes the target FundingLocked message into the passed io.Writer
@ -53,7 +61,9 @@ func (c *FundingLocked) Decode(r io.Reader, pver uint32) error {
func (c *FundingLocked) Encode(w io.Writer, pver uint32) error { func (c *FundingLocked) Encode(w io.Writer, pver uint32) error {
return WriteElements(w, return WriteElements(w,
c.ChanID, c.ChanID,
c.NextPerCommitmentPoint) c.NextPerCommitmentPoint,
c.ExtraData,
)
} }
// MsgType returns the uint32 code which uniquely identifies this message as a // MsgType returns the uint32 code which uniquely identifies this message as a
@ -70,14 +80,5 @@ func (c *FundingLocked) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (c *FundingLocked) MaxPayloadLength(uint32) uint32 { func (c *FundingLocked) MaxPayloadLength(uint32) uint32 {
var length uint32 return MaxMsgBody
// ChanID - 32 bytes
length += 32
// NextPerCommitmentPoint - 33 bytes
length += 33
// 65 bytes
return length
} }

View File

@ -13,6 +13,11 @@ type FundingSigned struct {
// CommitSig is Bob's signature for Alice's version of the commitment // CommitSig is Bob's signature for Alice's version of the commitment
// transaction. // transaction.
CommitSig Sig CommitSig Sig
// ExtraData is the set of data that was appended to this message to
// fill out the full maximum transport message size. These fields can
// be used to specify optional data such as custom TLV fields.
ExtraData ExtraOpaqueData
} }
// A compile time check to ensure FundingSigned implements the lnwire.Message // A compile time check to ensure FundingSigned implements the lnwire.Message
@ -25,7 +30,7 @@ var _ Message = (*FundingSigned)(nil)
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (f *FundingSigned) Encode(w io.Writer, pver uint32) error { func (f *FundingSigned) Encode(w io.Writer, pver uint32) error {
return WriteElements(w, f.ChanID, f.CommitSig) return WriteElements(w, f.ChanID, f.CommitSig, f.ExtraData)
} }
// Decode deserializes the serialized FundingSigned stored in the passed // Decode deserializes the serialized FundingSigned stored in the passed
@ -34,7 +39,7 @@ func (f *FundingSigned) Encode(w io.Writer, pver uint32) error {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (f *FundingSigned) Decode(r io.Reader, pver uint32) error { func (f *FundingSigned) Decode(r io.Reader, pver uint32) error {
return ReadElements(r, &f.ChanID, &f.CommitSig) return ReadElements(r, &f.ChanID, &f.CommitSig, &f.ExtraData)
} }
// MsgType returns the uint32 code which uniquely identifies this message as a // MsgType returns the uint32 code which uniquely identifies this message as a
@ -50,6 +55,5 @@ func (f *FundingSigned) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (f *FundingSigned) MaxPayloadLength(uint32) uint32 { func (f *FundingSigned) MaxPayloadLength(uint32) uint32 {
// 32 + 64 return MaxMsgBody
return 96
} }

View File

@ -24,6 +24,11 @@ type GossipTimestampRange struct {
// NOT send any announcements that have a timestamp greater than // NOT send any announcements that have a timestamp greater than
// FirstTimestamp + TimestampRange. // FirstTimestamp + TimestampRange.
TimestampRange uint32 TimestampRange uint32
// ExtraData is the set of data that was appended to this message to
// fill out the full maximum transport message size. These fields can
// be used to specify optional data such as custom TLV fields.
ExtraData ExtraOpaqueData
} }
// NewGossipTimestampRange creates a new empty GossipTimestampRange message. // NewGossipTimestampRange creates a new empty GossipTimestampRange message.
@ -44,6 +49,7 @@ func (g *GossipTimestampRange) Decode(r io.Reader, pver uint32) error {
g.ChainHash[:], g.ChainHash[:],
&g.FirstTimestamp, &g.FirstTimestamp,
&g.TimestampRange, &g.TimestampRange,
&g.ExtraData,
) )
} }
@ -56,6 +62,7 @@ func (g *GossipTimestampRange) Encode(w io.Writer, pver uint32) error {
g.ChainHash[:], g.ChainHash[:],
g.FirstTimestamp, g.FirstTimestamp,
g.TimestampRange, g.TimestampRange,
g.ExtraData,
) )
} }
@ -73,8 +80,5 @@ func (g *GossipTimestampRange) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (g *GossipTimestampRange) MaxPayloadLength(uint32) uint32 { func (g *GossipTimestampRange) MaxPayloadLength(uint32) uint32 {
// 32 + 4 + 4 return MaxMsgBody
//
// TODO(roasbeef): update to 8 byte timestmaps?
return 40
} }

View File

@ -20,6 +20,11 @@ type Init struct {
// message, any GlobalFeatures should be merged into the unified // message, any GlobalFeatures should be merged into the unified
// Features field. // Features field.
Features *RawFeatureVector Features *RawFeatureVector
// ExtraData is the set of data that was appended to this message to
// fill out the full maximum transport message size. These fields can
// be used to specify optional data such as custom TLV fields.
ExtraData ExtraOpaqueData
} }
// NewInitMessage creates new instance of init message object. // NewInitMessage creates new instance of init message object.
@ -27,6 +32,7 @@ func NewInitMessage(gf *RawFeatureVector, f *RawFeatureVector) *Init {
return &Init{ return &Init{
GlobalFeatures: gf, GlobalFeatures: gf,
Features: f, Features: f,
ExtraData: make([]byte, 0),
} }
} }
@ -42,6 +48,7 @@ func (msg *Init) Decode(r io.Reader, pver uint32) error {
return ReadElements(r, return ReadElements(r,
&msg.GlobalFeatures, &msg.GlobalFeatures,
&msg.Features, &msg.Features,
&msg.ExtraData,
) )
} }
@ -53,6 +60,7 @@ func (msg *Init) Encode(w io.Writer, pver uint32) error {
return WriteElements(w, return WriteElements(w,
msg.GlobalFeatures, msg.GlobalFeatures,
msg.Features, msg.Features,
msg.ExtraData,
) )
} }
@ -69,5 +77,5 @@ func (msg *Init) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (msg *Init) MaxPayloadLength(uint32) uint32 { func (msg *Init) MaxPayloadLength(uint32) uint32 {
return 2 + 2 + maxAllowedSize + 2 + maxAllowedSize return MaxMsgBody
} }

View File

@ -440,7 +440,9 @@ func TestLightningWireProtocol(t *testing.T) {
v[0] = reflect.ValueOf(req) v[0] = reflect.ValueOf(req)
}, },
MsgFundingCreated: func(v []reflect.Value, r *rand.Rand) { MsgFundingCreated: func(v []reflect.Value, r *rand.Rand) {
req := FundingCreated{} req := FundingCreated{
ExtraData: make([]byte, 0),
}
if _, err := r.Read(req.PendingChannelID[:]); err != nil { if _, err := r.Read(req.PendingChannelID[:]); err != nil {
t.Fatalf("unable to generate pending chan id: %v", err) t.Fatalf("unable to generate pending chan id: %v", err)
@ -471,7 +473,8 @@ func TestLightningWireProtocol(t *testing.T) {
} }
req := FundingSigned{ req := FundingSigned{
ChanID: ChannelID(c), ChanID: ChannelID(c),
ExtraData: make([]byte, 0),
} }
req.CommitSig, err = NewSigFromSignature(testSig) req.CommitSig, err = NewSigFromSignature(testSig)
if err != nil { if err != nil {
@ -502,6 +505,7 @@ func TestLightningWireProtocol(t *testing.T) {
MsgClosingSigned: func(v []reflect.Value, r *rand.Rand) { MsgClosingSigned: func(v []reflect.Value, r *rand.Rand) {
req := ClosingSigned{ req := ClosingSigned{
FeeSatoshis: btcutil.Amount(r.Int63()), FeeSatoshis: btcutil.Amount(r.Int63()),
ExtraData: make([]byte, 0),
} }
var err error var err error
req.Signature, err = NewSigFromSignature(testSig) req.Signature, err = NewSigFromSignature(testSig)
@ -570,8 +574,9 @@ func TestLightningWireProtocol(t *testing.T) {
MsgChannelAnnouncement: func(v []reflect.Value, r *rand.Rand) { MsgChannelAnnouncement: func(v []reflect.Value, r *rand.Rand) {
var err error var err error
req := ChannelAnnouncement{ req := ChannelAnnouncement{
ShortChannelID: NewShortChanIDFromInt(uint64(r.Int63())), ShortChannelID: NewShortChanIDFromInt(uint64(r.Int63())),
Features: randRawFeatureVector(r), Features: randRawFeatureVector(r),
ExtraOpaqueData: make([]byte, 0),
} }
req.NodeSig1, err = NewSigFromSignature(testSig) req.NodeSig1, err = NewSigFromSignature(testSig)
if err != nil { if err != nil {
@ -643,6 +648,7 @@ func TestLightningWireProtocol(t *testing.T) {
G: uint8(r.Int31()), G: uint8(r.Int31()),
B: uint8(r.Int31()), B: uint8(r.Int31()),
}, },
ExtraOpaqueData: make([]byte, 0),
} }
req.Signature, err = NewSigFromSignature(testSig) req.Signature, err = NewSigFromSignature(testSig)
if err != nil { if err != nil {
@ -698,6 +704,7 @@ func TestLightningWireProtocol(t *testing.T) {
HtlcMaximumMsat: maxHtlc, HtlcMaximumMsat: maxHtlc,
BaseFee: uint32(r.Int31()), BaseFee: uint32(r.Int31()),
FeeRate: uint32(r.Int31()), FeeRate: uint32(r.Int31()),
ExtraOpaqueData: make([]byte, 0),
} }
req.Signature, err = NewSigFromSignature(testSig) req.Signature, err = NewSigFromSignature(testSig)
if err != nil { if err != nil {
@ -726,7 +733,8 @@ func TestLightningWireProtocol(t *testing.T) {
MsgAnnounceSignatures: func(v []reflect.Value, r *rand.Rand) { MsgAnnounceSignatures: func(v []reflect.Value, r *rand.Rand) {
var err error var err error
req := AnnounceSignatures{ req := AnnounceSignatures{
ShortChannelID: NewShortChanIDFromInt(uint64(r.Int63())), ShortChannelID: NewShortChanIDFromInt(uint64(r.Int63())),
ExtraOpaqueData: make([]byte, 0),
} }
req.NodeSignature, err = NewSigFromSignature(testSig) req.NodeSignature, err = NewSigFromSignature(testSig)
@ -763,6 +771,7 @@ func TestLightningWireProtocol(t *testing.T) {
req := ChannelReestablish{ req := ChannelReestablish{
NextLocalCommitHeight: uint64(r.Int63()), NextLocalCommitHeight: uint64(r.Int63()),
RemoteCommitTailHeight: uint64(r.Int63()), RemoteCommitTailHeight: uint64(r.Int63()),
ExtraData: make([]byte, 0),
} }
// With a 50/50 probability, we'll include the // With a 50/50 probability, we'll include the
@ -785,7 +794,9 @@ func TestLightningWireProtocol(t *testing.T) {
v[0] = reflect.ValueOf(req) v[0] = reflect.ValueOf(req)
}, },
MsgQueryShortChanIDs: func(v []reflect.Value, r *rand.Rand) { MsgQueryShortChanIDs: func(v []reflect.Value, r *rand.Rand) {
req := QueryShortChanIDs{} req := QueryShortChanIDs{
ExtraData: make([]byte, 0),
}
// With a 50/50 change, we'll either use zlib encoding, // With a 50/50 change, we'll either use zlib encoding,
// or regular encoding. // or regular encoding.
@ -812,6 +823,7 @@ func TestLightningWireProtocol(t *testing.T) {
req := ReplyChannelRange{ req := ReplyChannelRange{
FirstBlockHeight: uint32(r.Int31()), FirstBlockHeight: uint32(r.Int31()),
NumBlocks: uint32(r.Int31()), NumBlocks: uint32(r.Int31()),
ExtraData: make([]byte, 0),
} }
if _, err := rand.Read(req.ChainHash[:]); err != nil { if _, err := rand.Read(req.ChainHash[:]); err != nil {

View File

@ -5,7 +5,6 @@ import (
"fmt" "fmt"
"image/color" "image/color"
"io" "io"
"io/ioutil"
"net" "net"
"unicode/utf8" "unicode/utf8"
) )
@ -98,7 +97,7 @@ type NodeAnnouncement struct {
// properly validate the set of signatures that cover these new fields, // properly validate the set of signatures that cover these new fields,
// and ensure we're able to make upgrades to the network in a forwards // and ensure we're able to make upgrades to the network in a forwards
// compatible manner. // compatible manner.
ExtraOpaqueData []byte ExtraOpaqueData ExtraOpaqueData
} }
// A compile time check to ensure NodeAnnouncement implements the // A compile time check to ensure NodeAnnouncement implements the
@ -110,7 +109,7 @@ var _ Message = (*NodeAnnouncement)(nil)
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (a *NodeAnnouncement) Decode(r io.Reader, pver uint32) error { func (a *NodeAnnouncement) Decode(r io.Reader, pver uint32) error {
err := ReadElements(r, return ReadElements(r,
&a.Signature, &a.Signature,
&a.Features, &a.Features,
&a.Timestamp, &a.Timestamp,
@ -118,24 +117,8 @@ func (a *NodeAnnouncement) Decode(r io.Reader, pver uint32) error {
&a.RGBColor, &a.RGBColor,
&a.Alias, &a.Alias,
&a.Addresses, &a.Addresses,
&a.ExtraOpaqueData,
) )
if err != nil {
return err
}
// Now that we've read out all the fields that we explicitly know of,
// we'll collect the remainder into the ExtraOpaqueData field. If there
// aren't any bytes, then we'll snip off the slice to avoid carrying
// around excess capacity.
a.ExtraOpaqueData, err = ioutil.ReadAll(r)
if err != nil {
return err
}
if len(a.ExtraOpaqueData) == 0 {
a.ExtraOpaqueData = nil
}
return nil
} }
// Encode serializes the target NodeAnnouncement into the passed io.Writer // Encode serializes the target NodeAnnouncement into the passed io.Writer
@ -167,7 +150,7 @@ func (a *NodeAnnouncement) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (a *NodeAnnouncement) MaxPayloadLength(pver uint32) uint32 { func (a *NodeAnnouncement) MaxPayloadLength(pver uint32) uint32 {
return 65533 return MaxMsgBody
} }
// DataToSign returns the part of the message that should be signed. // DataToSign returns the part of the message that should be signed.

View File

@ -20,11 +20,12 @@ var (
testOffset = uint16(24) testOffset = uint16(24)
sig, _ = NewSigFromSignature(testSig) sig, _ = NewSigFromSignature(testSig)
testChannelUpdate = ChannelUpdate{ testChannelUpdate = ChannelUpdate{
Signature: sig, Signature: sig,
ShortChannelID: NewShortChanIDFromInt(1), ShortChannelID: NewShortChanIDFromInt(1),
Timestamp: 1, Timestamp: 1,
MessageFlags: 0, MessageFlags: 0,
ChannelFlags: 1, ChannelFlags: 1,
ExtraOpaqueData: make([]byte, 0),
} }
) )

View File

@ -25,6 +25,11 @@ type QueryChannelRange struct {
// NumBlocks is the number of blocks beyond the first block that short // NumBlocks is the number of blocks beyond the first block that short
// channel ID's should be sent for. // channel ID's should be sent for.
NumBlocks uint32 NumBlocks uint32
// ExtraData is the set of data that was appended to this message to
// fill out the full maximum transport message size. These fields can
// be used to specify optional data such as custom TLV fields.
ExtraData ExtraOpaqueData
} }
// NewQueryChannelRange creates a new empty QueryChannelRange message. // NewQueryChannelRange creates a new empty QueryChannelRange message.
@ -45,6 +50,7 @@ func (q *QueryChannelRange) Decode(r io.Reader, pver uint32) error {
q.ChainHash[:], q.ChainHash[:],
&q.FirstBlockHeight, &q.FirstBlockHeight,
&q.NumBlocks, &q.NumBlocks,
&q.ExtraData,
) )
} }
@ -57,6 +63,7 @@ func (q *QueryChannelRange) Encode(w io.Writer, pver uint32) error {
q.ChainHash[:], q.ChainHash[:],
q.FirstBlockHeight, q.FirstBlockHeight,
q.NumBlocks, q.NumBlocks,
q.ExtraData,
) )
} }
@ -73,8 +80,7 @@ func (q *QueryChannelRange) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (q *QueryChannelRange) MaxPayloadLength(uint32) uint32 { func (q *QueryChannelRange) MaxPayloadLength(uint32) uint32 {
// 32 + 4 + 4 return MaxMsgBody
return 40
} }
// LastBlockHeight returns the last block height covered by the range of a // LastBlockHeight returns the last block height covered by the range of a

View File

@ -81,6 +81,11 @@ type QueryShortChanIDs struct {
// ShortChanIDs is a slice of decoded short channel ID's. // ShortChanIDs is a slice of decoded short channel ID's.
ShortChanIDs []ShortChannelID ShortChanIDs []ShortChannelID
// ExtraData is the set of data that was appended to this message to
// fill out the full maximum transport message size. These fields can
// be used to specify optional data such as custom TLV fields.
ExtraData ExtraOpaqueData
// noSort indicates whether or not to sort the short channel ids before // noSort indicates whether or not to sort the short channel ids before
// writing them out. // writing them out.
// //
@ -114,8 +119,11 @@ func (q *QueryShortChanIDs) Decode(r io.Reader, pver uint32) error {
} }
q.EncodingType, q.ShortChanIDs, err = decodeShortChanIDs(r) q.EncodingType, q.ShortChanIDs, err = decodeShortChanIDs(r)
if err != nil {
return err
}
return err return q.ExtraData.Decode(r)
} }
// decodeShortChanIDs decodes a set of short channel ID's that have been // decodeShortChanIDs decodes a set of short channel ID's that have been
@ -292,7 +300,12 @@ func (q *QueryShortChanIDs) Encode(w io.Writer, pver uint32) error {
// Base on our encoding type, we'll write out the set of short channel // Base on our encoding type, we'll write out the set of short channel
// ID's. // ID's.
return encodeShortChanIDs(w, q.EncodingType, q.ShortChanIDs, q.noSort) err = encodeShortChanIDs(w, q.EncodingType, q.ShortChanIDs, q.noSort)
if err != nil {
return err
}
return q.ExtraData.Encode(w)
} }
// encodeShortChanIDs encodes the passed short channel ID's into the passed // encodeShortChanIDs encodes the passed short channel ID's into the passed
@ -425,5 +438,5 @@ func (q *QueryShortChanIDs) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (q *QueryShortChanIDs) MaxPayloadLength(uint32) uint32 { func (q *QueryShortChanIDs) MaxPayloadLength(uint32) uint32 {
return MaxMessagePayload return MaxMsgBody
} }

View File

@ -37,6 +37,11 @@ type ReplyChannelRange struct {
// ShortChanIDs is a slice of decoded short channel ID's. // ShortChanIDs is a slice of decoded short channel ID's.
ShortChanIDs []ShortChannelID ShortChanIDs []ShortChannelID
// ExtraData is the set of data that was appended to this message to
// fill out the full maximum transport message size. These fields can
// be used to specify optional data such as custom TLV fields.
ExtraData ExtraOpaqueData
// noSort indicates whether or not to sort the short channel ids before // noSort indicates whether or not to sort the short channel ids before
// writing them out. // writing them out.
// //
@ -73,7 +78,7 @@ func (c *ReplyChannelRange) Decode(r io.Reader, pver uint32) error {
return err return err
} }
return err return c.ExtraData.Decode(r)
} }
// Encode serializes the target ReplyChannelRange into the passed io.Writer // Encode serializes the target ReplyChannelRange into the passed io.Writer
@ -96,7 +101,7 @@ func (c *ReplyChannelRange) Encode(w io.Writer, pver uint32) error {
return err return err
} }
return nil return c.ExtraData.Encode(w)
} }
// MsgType returns the integer uniquely identifying this message type on the // MsgType returns the integer uniquely identifying this message type on the
@ -112,7 +117,7 @@ func (c *ReplyChannelRange) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (c *ReplyChannelRange) MaxPayloadLength(uint32) uint32 { func (c *ReplyChannelRange) MaxPayloadLength(uint32) uint32 {
return MaxMessagePayload return MaxMsgBody
} }
// LastBlockHeight returns the last block height covered by the range of a // LastBlockHeight returns the last block height covered by the range of a

View File

@ -72,6 +72,7 @@ func TestReplyChannelRangeEmpty(t *testing.T) {
Complete: 1, Complete: 1,
EncodingType: test.encType, EncodingType: test.encType,
ShortChanIDs: nil, ShortChanIDs: nil,
ExtraData: make([]byte, 0),
} }
// First decode the hex string in the test case into a // First decode the hex string in the test case into a

View File

@ -22,6 +22,11 @@ type ReplyShortChanIDsEnd struct {
// set of short chan ID's in the corresponding QueryShortChanIDs // set of short chan ID's in the corresponding QueryShortChanIDs
// message. // message.
Complete uint8 Complete uint8
// ExtraData is the set of data that was appended to this message to
// fill out the full maximum transport message size. These fields can
// be used to specify optional data such as custom TLV fields.
ExtraData ExtraOpaqueData
} }
// NewReplyShortChanIDsEnd creates a new empty ReplyShortChanIDsEnd message. // NewReplyShortChanIDsEnd creates a new empty ReplyShortChanIDsEnd message.
@ -41,6 +46,7 @@ func (c *ReplyShortChanIDsEnd) Decode(r io.Reader, pver uint32) error {
return ReadElements(r, return ReadElements(r,
c.ChainHash[:], c.ChainHash[:],
&c.Complete, &c.Complete,
&c.ExtraData,
) )
} }
@ -52,6 +58,7 @@ func (c *ReplyShortChanIDsEnd) Encode(w io.Writer, pver uint32) error {
return WriteElements(w, return WriteElements(w,
c.ChainHash[:], c.ChainHash[:],
c.Complete, c.Complete,
c.ExtraData,
) )
} }
@ -69,6 +76,5 @@ func (c *ReplyShortChanIDsEnd) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (c *ReplyShortChanIDsEnd) MaxPayloadLength(uint32) uint32 { func (c *ReplyShortChanIDsEnd) MaxPayloadLength(uint32) uint32 {
// 32 (chain hash) + 1 (complete) return MaxMsgBody
return 33
} }

View File

@ -30,11 +30,18 @@ type RevokeAndAck struct {
// create the proper revocation key used within the commitment // create the proper revocation key used within the commitment
// transaction. // transaction.
NextRevocationKey *btcec.PublicKey NextRevocationKey *btcec.PublicKey
// ExtraData is the set of data that was appended to this message to
// fill out the full maximum transport message size. These fields can
// be used to specify optional data such as custom TLV fields.
ExtraData ExtraOpaqueData
} }
// NewRevokeAndAck creates a new RevokeAndAck message. // NewRevokeAndAck creates a new RevokeAndAck message.
func NewRevokeAndAck() *RevokeAndAck { func NewRevokeAndAck() *RevokeAndAck {
return &RevokeAndAck{} return &RevokeAndAck{
ExtraData: make([]byte, 0),
}
} }
// A compile time check to ensure RevokeAndAck implements the lnwire.Message // A compile time check to ensure RevokeAndAck implements the lnwire.Message
@ -50,6 +57,7 @@ func (c *RevokeAndAck) Decode(r io.Reader, pver uint32) error {
&c.ChanID, &c.ChanID,
c.Revocation[:], c.Revocation[:],
&c.NextRevocationKey, &c.NextRevocationKey,
&c.ExtraData,
) )
} }
@ -62,6 +70,7 @@ func (c *RevokeAndAck) Encode(w io.Writer, pver uint32) error {
c.ChanID, c.ChanID,
c.Revocation[:], c.Revocation[:],
c.NextRevocationKey, c.NextRevocationKey,
c.ExtraData,
) )
} }
@ -78,8 +87,7 @@ func (c *RevokeAndAck) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (c *RevokeAndAck) MaxPayloadLength(uint32) uint32 { func (c *RevokeAndAck) MaxPayloadLength(uint32) uint32 {
// 32 + 32 + 33 return MaxMsgBody
return 97
} }
// TargetChanID returns the channel id of the link for which this message is // TargetChanID returns the channel id of the link for which this message is

View File

@ -15,6 +15,11 @@ type Shutdown struct {
// Address is the script to which the channel funds will be paid. // Address is the script to which the channel funds will be paid.
Address DeliveryAddress Address DeliveryAddress
// ExtraData is the set of data that was appended to this message to
// fill out the full maximum transport message size. These fields can
// be used to specify optional data such as custom TLV fields.
ExtraData ExtraOpaqueData
} }
// DeliveryAddress is used to communicate the address to which funds from a // DeliveryAddress is used to communicate the address to which funds from a
@ -48,7 +53,7 @@ var _ Message = (*Shutdown)(nil)
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (s *Shutdown) Decode(r io.Reader, pver uint32) error { func (s *Shutdown) Decode(r io.Reader, pver uint32) error {
return ReadElements(r, &s.ChannelID, &s.Address) return ReadElements(r, &s.ChannelID, &s.Address, &s.ExtraData)
} }
// Encode serializes the target Shutdown into the passed io.Writer observing // Encode serializes the target Shutdown into the passed io.Writer observing
@ -56,7 +61,7 @@ func (s *Shutdown) Decode(r io.Reader, pver uint32) error {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (s *Shutdown) Encode(w io.Writer, pver uint32) error { func (s *Shutdown) Encode(w io.Writer, pver uint32) error {
return WriteElements(w, s.ChannelID, s.Address) return WriteElements(w, s.ChannelID, s.Address, s.ExtraData)
} }
// MsgType returns the integer uniquely identifying this message type on the // MsgType returns the integer uniquely identifying this message type on the
@ -72,16 +77,5 @@ func (s *Shutdown) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (s *Shutdown) MaxPayloadLength(pver uint32) uint32 { func (s *Shutdown) MaxPayloadLength(pver uint32) uint32 {
var length uint32 return MaxMsgBody
// ChannelID - 32bytes
length += 32
// Len - 2 bytes
length += 2
// ScriptPubKey - maximum delivery address size.
length += deliveryAddressMaxSize
return length
} }

View File

@ -52,6 +52,11 @@ type UpdateAddHTLC struct {
// should strip off a layer of encryption, exposing the next hop to be // should strip off a layer of encryption, exposing the next hop to be
// used in the subsequent UpdateAddHTLC message. // used in the subsequent UpdateAddHTLC message.
OnionBlob [OnionPacketSize]byte OnionBlob [OnionPacketSize]byte
// ExtraData is the set of data that was appended to this message to
// fill out the full maximum transport message size. These fields can
// be used to specify optional data such as custom TLV fields.
ExtraData ExtraOpaqueData
} }
// NewUpdateAddHTLC returns a new empty UpdateAddHTLC message. // NewUpdateAddHTLC returns a new empty UpdateAddHTLC message.
@ -75,6 +80,7 @@ func (c *UpdateAddHTLC) Decode(r io.Reader, pver uint32) error {
c.PaymentHash[:], c.PaymentHash[:],
&c.Expiry, &c.Expiry,
c.OnionBlob[:], c.OnionBlob[:],
&c.ExtraData,
) )
} }
@ -90,6 +96,7 @@ func (c *UpdateAddHTLC) Encode(w io.Writer, pver uint32) error {
c.PaymentHash[:], c.PaymentHash[:],
c.Expiry, c.Expiry,
c.OnionBlob[:], c.OnionBlob[:],
c.ExtraData,
) )
} }
@ -106,8 +113,7 @@ func (c *UpdateAddHTLC) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (c *UpdateAddHTLC) MaxPayloadLength(uint32) uint32 { func (c *UpdateAddHTLC) MaxPayloadLength(uint32) uint32 {
// 1450 return MaxMsgBody
return 32 + 8 + 4 + 8 + 32 + 1366
} }
// TargetChanID returns the channel id of the link for which this message is // TargetChanID returns the channel id of the link for which this message is

View File

@ -26,6 +26,11 @@ type UpdateFailHTLC struct {
// failed. This blob is only fully decryptable by the initiator of the // failed. This blob is only fully decryptable by the initiator of the
// HTLC message. // HTLC message.
Reason OpaqueReason Reason OpaqueReason
// ExtraData is the set of data that was appended to this message to
// fill out the full maximum transport message size. These fields can
// be used to specify optional data such as custom TLV fields.
ExtraData ExtraOpaqueData
} }
// A compile time check to ensure UpdateFailHTLC implements the lnwire.Message // A compile time check to ensure UpdateFailHTLC implements the lnwire.Message
@ -41,6 +46,7 @@ func (c *UpdateFailHTLC) Decode(r io.Reader, pver uint32) error {
&c.ChanID, &c.ChanID,
&c.ID, &c.ID,
&c.Reason, &c.Reason,
&c.ExtraData,
) )
} }
@ -53,6 +59,7 @@ func (c *UpdateFailHTLC) Encode(w io.Writer, pver uint32) error {
c.ChanID, c.ChanID,
c.ID, c.ID,
c.Reason, c.Reason,
c.ExtraData,
) )
} }
@ -69,21 +76,7 @@ func (c *UpdateFailHTLC) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (c *UpdateFailHTLC) MaxPayloadLength(uint32) uint32 { func (c *UpdateFailHTLC) MaxPayloadLength(uint32) uint32 {
var length uint32 return MaxMsgBody
// Length of the ChanID
length += 32
// Length of the ID
length += 8
// Length of the length opaque reason
length += 2
// Length of the Reason
length += 292
return length
} }
// TargetChanID returns the channel id of the link for which this message is // TargetChanID returns the channel id of the link for which this message is

View File

@ -24,6 +24,11 @@ type UpdateFailMalformedHTLC struct {
// FailureCode the exact reason why onion blob haven't been parsed. // FailureCode the exact reason why onion blob haven't been parsed.
FailureCode FailCode FailureCode FailCode
// ExtraData is the set of data that was appended to this message to
// fill out the full maximum transport message size. These fields can
// be used to specify optional data such as custom TLV fields.
ExtraData ExtraOpaqueData
} }
// A compile time check to ensure UpdateFailMalformedHTLC implements the // A compile time check to ensure UpdateFailMalformedHTLC implements the
@ -40,6 +45,7 @@ func (c *UpdateFailMalformedHTLC) Decode(r io.Reader, pver uint32) error {
&c.ID, &c.ID,
c.ShaOnionBlob[:], c.ShaOnionBlob[:],
&c.FailureCode, &c.FailureCode,
&c.ExtraData,
) )
} }
@ -53,6 +59,7 @@ func (c *UpdateFailMalformedHTLC) Encode(w io.Writer, pver uint32) error {
c.ID, c.ID,
c.ShaOnionBlob[:], c.ShaOnionBlob[:],
c.FailureCode, c.FailureCode,
c.ExtraData,
) )
} }
@ -70,8 +77,7 @@ func (c *UpdateFailMalformedHTLC) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (c *UpdateFailMalformedHTLC) MaxPayloadLength(uint32) uint32 { func (c *UpdateFailMalformedHTLC) MaxPayloadLength(uint32) uint32 {
// 32 + 8 + 32 + 2 return MaxMsgBody
return 74
} }
// TargetChanID returns the channel id of the link for which this message is // TargetChanID returns the channel id of the link for which this message is

View File

@ -16,6 +16,11 @@ type UpdateFee struct {
// TODO(halseth): make SatPerKWeight when fee estimation is moved to // TODO(halseth): make SatPerKWeight when fee estimation is moved to
// own package. Currently this will cause an import cycle. // own package. Currently this will cause an import cycle.
FeePerKw uint32 FeePerKw uint32
// ExtraData is the set of data that was appended to this message to
// fill out the full maximum transport message size. These fields can
// be used to specify optional data such as custom TLV fields.
ExtraData ExtraOpaqueData
} }
// NewUpdateFee creates a new UpdateFee message. // NewUpdateFee creates a new UpdateFee message.
@ -38,6 +43,7 @@ func (c *UpdateFee) Decode(r io.Reader, pver uint32) error {
return ReadElements(r, return ReadElements(r,
&c.ChanID, &c.ChanID,
&c.FeePerKw, &c.FeePerKw,
&c.ExtraData,
) )
} }
@ -49,6 +55,7 @@ func (c *UpdateFee) Encode(w io.Writer, pver uint32) error {
return WriteElements(w, return WriteElements(w,
c.ChanID, c.ChanID,
c.FeePerKw, c.FeePerKw,
c.ExtraData,
) )
} }
@ -65,8 +72,7 @@ func (c *UpdateFee) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (c *UpdateFee) MaxPayloadLength(uint32) uint32 { func (c *UpdateFee) MaxPayloadLength(uint32) uint32 {
// 32 + 4 return MaxMsgBody
return 36
} }
// TargetChanID returns the channel id of the link for which this message is // TargetChanID returns the channel id of the link for which this message is

View File

@ -21,6 +21,11 @@ type UpdateFulfillHTLC struct {
// PaymentPreimage is the R-value preimage required to fully settle an // PaymentPreimage is the R-value preimage required to fully settle an
// HTLC. // HTLC.
PaymentPreimage [32]byte PaymentPreimage [32]byte
// ExtraData is the set of data that was appended to this message to
// fill out the full maximum transport message size. These fields can
// be used to specify optional data such as custom TLV fields.
ExtraData ExtraOpaqueData
} }
// NewUpdateFulfillHTLC returns a new empty UpdateFulfillHTLC. // NewUpdateFulfillHTLC returns a new empty UpdateFulfillHTLC.
@ -47,6 +52,7 @@ func (c *UpdateFulfillHTLC) Decode(r io.Reader, pver uint32) error {
&c.ChanID, &c.ChanID,
&c.ID, &c.ID,
c.PaymentPreimage[:], c.PaymentPreimage[:],
&c.ExtraData,
) )
} }
@ -59,6 +65,7 @@ func (c *UpdateFulfillHTLC) Encode(w io.Writer, pver uint32) error {
c.ChanID, c.ChanID,
c.ID, c.ID,
c.PaymentPreimage[:], c.PaymentPreimage[:],
c.ExtraData,
) )
} }
@ -75,8 +82,7 @@ func (c *UpdateFulfillHTLC) MsgType() MessageType {
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (c *UpdateFulfillHTLC) MaxPayloadLength(uint32) uint32 { func (c *UpdateFulfillHTLC) MaxPayloadLength(uint32) uint32 {
// 32 + 8 + 32 return MaxMsgBody
return 72
} }
// TargetChanID returns the channel id of the link for which this message is // TargetChanID returns the channel id of the link for which this message is