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

@ -608,6 +608,7 @@ func TestChannelStateTransition(t *testing.T) {
LogIndex: 2,
UpdateMsg: &lnwire.UpdateAddHTLC{
ChanID: lnwire.ChannelID{1, 2, 3},
ExtraData: make([]byte, 0),
},
},
}
@ -628,7 +629,9 @@ func TestChannelStateTransition(t *testing.T) {
if !reflect.DeepEqual(
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
@ -670,6 +673,7 @@ func TestChannelStateTransition(t *testing.T) {
wireSig,
wireSig,
},
ExtraData: make([]byte, 0),
},
LogUpdates: []LogUpdate{
{
@ -678,6 +682,7 @@ func TestChannelStateTransition(t *testing.T) {
ID: 1,
Amount: lnwire.NewMSatFromSatoshis(100),
Expiry: 25,
ExtraData: make([]byte, 0),
},
},
{
@ -686,6 +691,7 @@ func TestChannelStateTransition(t *testing.T) {
ID: 2,
Amount: lnwire.NewMSatFromSatoshis(200),
Expiry: 50,
ExtraData: make([]byte, 0),
},
},
},

@ -5,6 +5,7 @@ import (
"reflect"
"github.com/davecgh/go-spew/spew"
"github.com/go-errors/errors"
"github.com/lightningnetwork/lnd/lnwire"
)
@ -23,6 +24,7 @@ func TestWaitingProofStore(t *testing.T) {
proof1 := NewWaitingProof(true, &lnwire.AnnounceSignatures{
NodeSignature: wireSig,
BitcoinSignature: wireSig,
ExtraOpaqueData: make([]byte, 0),
})
store, err := NewWaitingProofStore(db)
@ -40,7 +42,8 @@ func TestWaitingProofStore(t *testing.T) {
t.Fatalf("unable retrieve proof from storage: %v", err)
}
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 {

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

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

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

@ -2,7 +2,6 @@ package lnwire
import (
"io"
"io/ioutil"
)
// 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,
// and ensure we're able to make upgrades to the network in a forwards
// compatible manner.
ExtraOpaqueData []byte
ExtraOpaqueData ExtraOpaqueData
}
// 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.
func (a *AnnounceSignatures) Decode(r io.Reader, pver uint32) error {
err := ReadElements(r,
return ReadElements(r,
&a.ChannelID,
&a.ShortChannelID,
&a.NodeSignature,
&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
@ -104,5 +87,5 @@ func (a *AnnounceSignatures) MsgType() MessageType {
//
// This is part of the lnwire.Message interface.
func (a *AnnounceSignatures) MaxPayloadLength(pver uint32) uint32 {
return 65533
return MaxMsgBody
}

@ -3,7 +3,6 @@ package lnwire
import (
"bytes"
"io"
"io/ioutil"
"github.com/btcsuite/btcd/chaincfg/chainhash"
)
@ -56,7 +55,7 @@ type ChannelAnnouncement struct {
// 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
// compatible manner.
ExtraOpaqueData []byte
ExtraOpaqueData ExtraOpaqueData
}
// 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.
func (a *ChannelAnnouncement) Decode(r io.Reader, pver uint32) error {
err := ReadElements(r,
return ReadElements(r,
&a.NodeSig1,
&a.NodeSig2,
&a.BitcoinSig1,
@ -80,24 +79,8 @@ func (a *ChannelAnnouncement) Decode(r io.Reader, pver uint32) error {
&a.NodeID2,
&a.BitcoinKey1,
&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
@ -134,7 +117,7 @@ func (a *ChannelAnnouncement) MsgType() MessageType {
//
// This is part of the lnwire.Message interface.
func (a *ChannelAnnouncement) MaxPayloadLength(pver uint32) uint32 {
return 65533
return MaxMsgBody
}
// DataToSign is used to retrieve part of the announcement message which should

@ -60,6 +60,11 @@ type ChannelReestablish struct {
// LocalUnrevokedCommitPoint is the commitment point used in the
// current un-revoked commitment transaction of the sending party.
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
@ -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
// remaining fields as they're optional.
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.
return WriteElements(w, a.LastRemoteCommitSecret[:],
a.LocalUnrevokedCommitPoint)
return WriteElements(w,
a.LastRemoteCommitSecret[:],
a.LocalUnrevokedCommitPoint,
a.ExtraData,
)
}
// 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
_, err = io.ReadFull(r, buf[:32])
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
} else if err != nil {
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
// the error in this case, as it has included the commit secret, then
// 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
@ -145,22 +165,5 @@ func (a *ChannelReestablish) MsgType() MessageType {
//
// This is part of the lnwire.Message interface.
func (a *ChannelReestablish) MaxPayloadLength(pver uint32) uint32 {
var length uint32
// 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
return MaxMsgBody
}

@ -4,7 +4,6 @@ import (
"bytes"
"fmt"
"io"
"io/ioutil"
"github.com/btcsuite/btcd/chaincfg/chainhash"
)
@ -115,13 +114,10 @@ type ChannelUpdate struct {
// HtlcMaximumMsat is the maximum HTLC value which will be accepted.
HtlcMaximumMsat MilliSatoshi
// ExtraOpaqueData is the set of data that was appended to this
// message, some of which we may not actually know how to iterate or
// parse. By holding onto this data, we ensure that we're able to
// 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
// compatible manner.
ExtraOpaqueData []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.
ExtraOpaqueData ExtraOpaqueData
}
// 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,
// 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
return a.ExtraOpaqueData.Decode(r)
}
// 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.
return WriteElements(w, a.ExtraOpaqueData)
return a.ExtraOpaqueData.Encode(w)
}
// 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.
func (a *ChannelUpdate) MaxPayloadLength(pver uint32) uint32 {
return 65533
return MaxMsgBody
}
// 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.
if err := WriteElements(&w, a.ExtraOpaqueData); err != nil {
if err := a.ExtraOpaqueData.Encode(&w); err != nil {
return nil, err
}

@ -27,6 +27,11 @@ type ClosingSigned struct {
// Signature is for the proposed channel close transaction.
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.
@ -49,7 +54,9 @@ var _ Message = (*ClosingSigned)(nil)
//
// This is part of the lnwire.Message interface.
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
@ -57,7 +64,9 @@ func (c *ClosingSigned) Decode(r io.Reader, pver uint32) error {
//
// This is part of the lnwire.Message interface.
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
@ -73,16 +82,5 @@ func (c *ClosingSigned) MsgType() MessageType {
//
// This is part of the lnwire.Message interface.
func (c *ClosingSigned) MaxPayloadLength(uint32) uint32 {
var length uint32
// ChannelID - 32 bytes
length += 32
// FeeSatoshis - 8 bytes
length += 8
// Signature - 64 bytes
length += 64
return length
return MaxMsgBody
}

@ -34,11 +34,18 @@ type CommitSig struct {
// should be signed, for each incoming HTLC the HTLC timeout
// transaction should be signed.
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.
func NewCommitSig() *CommitSig {
return &CommitSig{}
return &CommitSig{
ExtraData: make([]byte, 0),
}
}
// 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.CommitSig,
&c.HtlcSigs,
&c.ExtraData,
)
}
@ -66,6 +74,7 @@ func (c *CommitSig) Encode(w io.Writer, pver uint32) error {
c.ChanID,
c.CommitSig,
c.HtlcSigs,
c.ExtraData,
)
}
@ -82,8 +91,7 @@ func (c *CommitSig) MsgType() MessageType {
//
// This is part of the lnwire.Message interface.
func (c *CommitSig) MaxPayloadLength(uint32) uint32 {
// 32 + 64 + 2 + max_allowed_htlcs
return MaxMessagePayload
return MaxMsgBody
}
// TargetChanID returns the channel id of the link for which this message is

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

@ -24,6 +24,11 @@ type FundingCreated struct {
// CommitSig is Alice's signature from Bob's version of the commitment
// transaction.
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
@ -36,7 +41,10 @@ var _ Message = (*FundingCreated)(nil)
//
// This is part of the lnwire.Message interface.
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
@ -45,7 +53,10 @@ func (f *FundingCreated) Encode(w io.Writer, pver uint32) error {
//
// This is part of the lnwire.Message interface.
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
@ -61,6 +72,5 @@ func (f *FundingCreated) MsgType() MessageType {
//
// This is part of the lnwire.Message interface.
func (f *FundingCreated) MaxPayloadLength(uint32) uint32 {
// 32 + 32 + 2 + 64
return 130
return MaxMsgBody
}

@ -19,6 +19,11 @@ type FundingLocked struct {
// NextPerCommitmentPoint is the secret that can be used to revoke the
// next commitment transaction for the channel.
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
@ -27,6 +32,7 @@ func NewFundingLocked(cid ChannelID, npcp *btcec.PublicKey) *FundingLocked {
return &FundingLocked{
ChanID: cid,
NextPerCommitmentPoint: npcp,
ExtraData: make([]byte, 0),
}
}
@ -42,7 +48,9 @@ var _ Message = (*FundingLocked)(nil)
func (c *FundingLocked) Decode(r io.Reader, pver uint32) error {
return ReadElements(r,
&c.ChanID,
&c.NextPerCommitmentPoint)
&c.NextPerCommitmentPoint,
&c.ExtraData,
)
}
// 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 {
return WriteElements(w,
c.ChanID,
c.NextPerCommitmentPoint)
c.NextPerCommitmentPoint,
c.ExtraData,
)
}
// 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.
func (c *FundingLocked) MaxPayloadLength(uint32) uint32 {
var length uint32
// ChanID - 32 bytes
length += 32
// NextPerCommitmentPoint - 33 bytes
length += 33
// 65 bytes
return length
return MaxMsgBody
}

@ -13,6 +13,11 @@ type FundingSigned struct {
// CommitSig is Bob's signature for Alice's version of the commitment
// transaction.
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
@ -25,7 +30,7 @@ var _ Message = (*FundingSigned)(nil)
//
// This is part of the lnwire.Message interface.
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
@ -34,7 +39,7 @@ func (f *FundingSigned) Encode(w io.Writer, pver uint32) error {
//
// This is part of the lnwire.Message interface.
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
@ -50,6 +55,5 @@ func (f *FundingSigned) MsgType() MessageType {
//
// This is part of the lnwire.Message interface.
func (f *FundingSigned) MaxPayloadLength(uint32) uint32 {
// 32 + 64
return 96
return MaxMsgBody
}

@ -24,6 +24,11 @@ type GossipTimestampRange struct {
// NOT send any announcements that have a timestamp greater than
// FirstTimestamp + TimestampRange.
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.
@ -44,6 +49,7 @@ func (g *GossipTimestampRange) Decode(r io.Reader, pver uint32) error {
g.ChainHash[:],
&g.FirstTimestamp,
&g.TimestampRange,
&g.ExtraData,
)
}
@ -56,6 +62,7 @@ func (g *GossipTimestampRange) Encode(w io.Writer, pver uint32) error {
g.ChainHash[:],
g.FirstTimestamp,
g.TimestampRange,
g.ExtraData,
)
}
@ -73,8 +80,5 @@ func (g *GossipTimestampRange) MsgType() MessageType {
//
// This is part of the lnwire.Message interface.
func (g *GossipTimestampRange) MaxPayloadLength(uint32) uint32 {
// 32 + 4 + 4
//
// TODO(roasbeef): update to 8 byte timestmaps?
return 40
return MaxMsgBody
}

@ -20,6 +20,11 @@ type Init struct {
// message, any GlobalFeatures should be merged into the unified
// Features field.
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.
@ -27,6 +32,7 @@ func NewInitMessage(gf *RawFeatureVector, f *RawFeatureVector) *Init {
return &Init{
GlobalFeatures: gf,
Features: f,
ExtraData: make([]byte, 0),
}
}
@ -42,6 +48,7 @@ func (msg *Init) Decode(r io.Reader, pver uint32) error {
return ReadElements(r,
&msg.GlobalFeatures,
&msg.Features,
&msg.ExtraData,
)
}
@ -53,6 +60,7 @@ func (msg *Init) Encode(w io.Writer, pver uint32) error {
return WriteElements(w,
msg.GlobalFeatures,
msg.Features,
msg.ExtraData,
)
}
@ -69,5 +77,5 @@ func (msg *Init) MsgType() MessageType {
//
// This is part of the lnwire.Message interface.
func (msg *Init) MaxPayloadLength(uint32) uint32 {
return 2 + 2 + maxAllowedSize + 2 + maxAllowedSize
return MaxMsgBody
}

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

@ -5,7 +5,6 @@ import (
"fmt"
"image/color"
"io"
"io/ioutil"
"net"
"unicode/utf8"
)
@ -98,7 +97,7 @@ type NodeAnnouncement struct {
// 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
// compatible manner.
ExtraOpaqueData []byte
ExtraOpaqueData ExtraOpaqueData
}
// 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.
func (a *NodeAnnouncement) Decode(r io.Reader, pver uint32) error {
err := ReadElements(r,
return ReadElements(r,
&a.Signature,
&a.Features,
&a.Timestamp,
@ -118,24 +117,8 @@ func (a *NodeAnnouncement) Decode(r io.Reader, pver uint32) error {
&a.RGBColor,
&a.Alias,
&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
@ -167,7 +150,7 @@ func (a *NodeAnnouncement) MsgType() MessageType {
//
// This is part of the lnwire.Message interface.
func (a *NodeAnnouncement) MaxPayloadLength(pver uint32) uint32 {
return 65533
return MaxMsgBody
}
// DataToSign returns the part of the message that should be signed.

@ -25,6 +25,7 @@ var (
Timestamp: 1,
MessageFlags: 0,
ChannelFlags: 1,
ExtraOpaqueData: make([]byte, 0),
}
)

@ -25,6 +25,11 @@ type QueryChannelRange struct {
// NumBlocks is the number of blocks beyond the first block that short
// channel ID's should be sent for.
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.
@ -45,6 +50,7 @@ func (q *QueryChannelRange) Decode(r io.Reader, pver uint32) error {
q.ChainHash[:],
&q.FirstBlockHeight,
&q.NumBlocks,
&q.ExtraData,
)
}
@ -57,6 +63,7 @@ func (q *QueryChannelRange) Encode(w io.Writer, pver uint32) error {
q.ChainHash[:],
q.FirstBlockHeight,
q.NumBlocks,
q.ExtraData,
)
}
@ -73,8 +80,7 @@ func (q *QueryChannelRange) MsgType() MessageType {
//
// This is part of the lnwire.Message interface.
func (q *QueryChannelRange) MaxPayloadLength(uint32) uint32 {
// 32 + 4 + 4
return 40
return MaxMsgBody
}
// LastBlockHeight returns the last block height covered by the range of a

@ -81,6 +81,11 @@ type QueryShortChanIDs struct {
// ShortChanIDs is a slice of decoded short channel ID's.
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
// writing them out.
//
@ -114,8 +119,11 @@ func (q *QueryShortChanIDs) Decode(r io.Reader, pver uint32) error {
}
q.EncodingType, q.ShortChanIDs, err = decodeShortChanIDs(r)
if err != nil {
return err
}
return q.ExtraData.Decode(r)
}
// 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
// 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
@ -425,5 +438,5 @@ func (q *QueryShortChanIDs) MsgType() MessageType {
//
// This is part of the lnwire.Message interface.
func (q *QueryShortChanIDs) MaxPayloadLength(uint32) uint32 {
return MaxMessagePayload
return MaxMsgBody
}

@ -37,6 +37,11 @@ type ReplyChannelRange struct {
// ShortChanIDs is a slice of decoded short channel ID's.
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
// writing them out.
//
@ -73,7 +78,7 @@ func (c *ReplyChannelRange) Decode(r io.Reader, pver uint32) error {
return err
}
return err
return c.ExtraData.Decode(r)
}
// 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 nil
return c.ExtraData.Encode(w)
}
// 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.
func (c *ReplyChannelRange) MaxPayloadLength(uint32) uint32 {
return MaxMessagePayload
return MaxMsgBody
}
// LastBlockHeight returns the last block height covered by the range of a

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

@ -22,6 +22,11 @@ type ReplyShortChanIDsEnd struct {
// set of short chan ID's in the corresponding QueryShortChanIDs
// message.
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.
@ -41,6 +46,7 @@ func (c *ReplyShortChanIDsEnd) Decode(r io.Reader, pver uint32) error {
return ReadElements(r,
c.ChainHash[:],
&c.Complete,
&c.ExtraData,
)
}
@ -52,6 +58,7 @@ func (c *ReplyShortChanIDsEnd) Encode(w io.Writer, pver uint32) error {
return WriteElements(w,
c.ChainHash[:],
c.Complete,
c.ExtraData,
)
}
@ -69,6 +76,5 @@ func (c *ReplyShortChanIDsEnd) MsgType() MessageType {
//
// This is part of the lnwire.Message interface.
func (c *ReplyShortChanIDsEnd) MaxPayloadLength(uint32) uint32 {
// 32 (chain hash) + 1 (complete)
return 33
return MaxMsgBody
}

@ -30,11 +30,18 @@ type RevokeAndAck struct {
// create the proper revocation key used within the commitment
// transaction.
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.
func NewRevokeAndAck() *RevokeAndAck {
return &RevokeAndAck{}
return &RevokeAndAck{
ExtraData: make([]byte, 0),
}
}
// 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.Revocation[:],
&c.NextRevocationKey,
&c.ExtraData,
)
}
@ -62,6 +70,7 @@ func (c *RevokeAndAck) Encode(w io.Writer, pver uint32) error {
c.ChanID,
c.Revocation[:],
c.NextRevocationKey,
c.ExtraData,
)
}
@ -78,8 +87,7 @@ func (c *RevokeAndAck) MsgType() MessageType {
//
// This is part of the lnwire.Message interface.
func (c *RevokeAndAck) MaxPayloadLength(uint32) uint32 {
// 32 + 32 + 33
return 97
return MaxMsgBody
}
// TargetChanID returns the channel id of the link for which this message is

@ -15,6 +15,11 @@ type Shutdown struct {
// Address is the script to which the channel funds will be paid.
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
@ -48,7 +53,7 @@ var _ Message = (*Shutdown)(nil)
//
// This is part of the lnwire.Message interface.
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
@ -56,7 +61,7 @@ func (s *Shutdown) Decode(r io.Reader, pver uint32) error {
//
// This is part of the lnwire.Message interface.
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
@ -72,16 +77,5 @@ func (s *Shutdown) MsgType() MessageType {
//
// This is part of the lnwire.Message interface.
func (s *Shutdown) MaxPayloadLength(pver uint32) uint32 {
var length uint32
// ChannelID - 32bytes
length += 32
// Len - 2 bytes
length += 2
// ScriptPubKey - maximum delivery address size.
length += deliveryAddressMaxSize
return length
return MaxMsgBody
}

@ -52,6 +52,11 @@ type UpdateAddHTLC struct {
// should strip off a layer of encryption, exposing the next hop to be
// used in the subsequent UpdateAddHTLC message.
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.
@ -75,6 +80,7 @@ func (c *UpdateAddHTLC) Decode(r io.Reader, pver uint32) error {
c.PaymentHash[:],
&c.Expiry,
c.OnionBlob[:],
&c.ExtraData,
)
}
@ -90,6 +96,7 @@ func (c *UpdateAddHTLC) Encode(w io.Writer, pver uint32) error {
c.PaymentHash[:],
c.Expiry,
c.OnionBlob[:],
c.ExtraData,
)
}
@ -106,8 +113,7 @@ func (c *UpdateAddHTLC) MsgType() MessageType {
//
// This is part of the lnwire.Message interface.
func (c *UpdateAddHTLC) MaxPayloadLength(uint32) uint32 {
// 1450
return 32 + 8 + 4 + 8 + 32 + 1366
return MaxMsgBody
}
// TargetChanID returns the channel id of the link for which this message is

@ -26,6 +26,11 @@ type UpdateFailHTLC struct {
// failed. This blob is only fully decryptable by the initiator of the
// HTLC message.
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
@ -41,6 +46,7 @@ func (c *UpdateFailHTLC) Decode(r io.Reader, pver uint32) error {
&c.ChanID,
&c.ID,
&c.Reason,
&c.ExtraData,
)
}
@ -53,6 +59,7 @@ func (c *UpdateFailHTLC) Encode(w io.Writer, pver uint32) error {
c.ChanID,
c.ID,
c.Reason,
c.ExtraData,
)
}
@ -69,21 +76,7 @@ func (c *UpdateFailHTLC) MsgType() MessageType {
//
// This is part of the lnwire.Message interface.
func (c *UpdateFailHTLC) MaxPayloadLength(uint32) uint32 {
var length uint32
// 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
return MaxMsgBody
}
// TargetChanID returns the channel id of the link for which this message is

@ -24,6 +24,11 @@ type UpdateFailMalformedHTLC struct {
// FailureCode the exact reason why onion blob haven't been parsed.
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
@ -40,6 +45,7 @@ func (c *UpdateFailMalformedHTLC) Decode(r io.Reader, pver uint32) error {
&c.ID,
c.ShaOnionBlob[:],
&c.FailureCode,
&c.ExtraData,
)
}
@ -53,6 +59,7 @@ func (c *UpdateFailMalformedHTLC) Encode(w io.Writer, pver uint32) error {
c.ID,
c.ShaOnionBlob[:],
c.FailureCode,
c.ExtraData,
)
}
@ -70,8 +77,7 @@ func (c *UpdateFailMalformedHTLC) MsgType() MessageType {
//
// This is part of the lnwire.Message interface.
func (c *UpdateFailMalformedHTLC) MaxPayloadLength(uint32) uint32 {
// 32 + 8 + 32 + 2
return 74
return MaxMsgBody
}
// TargetChanID returns the channel id of the link for which this message is

@ -16,6 +16,11 @@ type UpdateFee struct {
// TODO(halseth): make SatPerKWeight when fee estimation is moved to
// own package. Currently this will cause an import cycle.
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.
@ -38,6 +43,7 @@ func (c *UpdateFee) Decode(r io.Reader, pver uint32) error {
return ReadElements(r,
&c.ChanID,
&c.FeePerKw,
&c.ExtraData,
)
}
@ -49,6 +55,7 @@ func (c *UpdateFee) Encode(w io.Writer, pver uint32) error {
return WriteElements(w,
c.ChanID,
c.FeePerKw,
c.ExtraData,
)
}
@ -65,8 +72,7 @@ func (c *UpdateFee) MsgType() MessageType {
//
// This is part of the lnwire.Message interface.
func (c *UpdateFee) MaxPayloadLength(uint32) uint32 {
// 32 + 4
return 36
return MaxMsgBody
}
// TargetChanID returns the channel id of the link for which this message is

@ -21,6 +21,11 @@ type UpdateFulfillHTLC struct {
// PaymentPreimage is the R-value preimage required to fully settle an
// HTLC.
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.
@ -47,6 +52,7 @@ func (c *UpdateFulfillHTLC) Decode(r io.Reader, pver uint32) error {
&c.ChanID,
&c.ID,
c.PaymentPreimage[:],
&c.ExtraData,
)
}
@ -59,6 +65,7 @@ func (c *UpdateFulfillHTLC) Encode(w io.Writer, pver uint32) error {
c.ChanID,
c.ID,
c.PaymentPreimage[:],
c.ExtraData,
)
}
@ -75,8 +82,7 @@ func (c *UpdateFulfillHTLC) MsgType() MessageType {
//
// This is part of the lnwire.Message interface.
func (c *UpdateFulfillHTLC) MaxPayloadLength(uint32) uint32 {
// 32 + 8 + 32
return 72
return MaxMsgBody
}
// TargetChanID returns the channel id of the link for which this message is