From 9a6bb1977050f988bcd24da5a43c72d52dcaf532 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Mon, 27 Jan 2020 17:25:36 -0800 Subject: [PATCH] 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. --- channeldb/channel_test.go | 22 ++++++++----- channeldb/waitingproof_test.go | 5 ++- discovery/message_store_test.go | 6 ++-- htlcswitch/payment_result_test.go | 15 +++++---- lnwallet/channel_test.go | 2 ++ lnwire/announcement_signatures.go | 25 +++------------ lnwire/channel_announcement.go | 25 +++------------ lnwire/channel_reestablish.go | 47 +++++++++++++++------------- lnwire/channel_update.go | 32 +++++-------------- lnwire/closing_signed.go | 26 +++++++-------- lnwire/commit_sig.go | 14 +++++++-- lnwire/error.go | 3 +- lnwire/funding_created.go | 18 ++++++++--- lnwire/funding_locked.go | 25 ++++++++------- lnwire/funding_signed.go | 12 ++++--- lnwire/gossip_timestamp_range.go | 12 ++++--- lnwire/init_message.go | 10 +++++- lnwire/lnwire_test.go | 24 ++++++++++---- lnwire/node_announcement.go | 25 +++------------ lnwire/onion_error_test.go | 11 ++++--- lnwire/query_channel_range.go | 10 ++++-- lnwire/query_short_chan_ids.go | 19 +++++++++-- lnwire/reply_channel_range.go | 11 +++++-- lnwire/reply_channel_range_test.go | 1 + lnwire/reply_short_chan_ids_end.go | 10 ++++-- lnwire/revoke_and_ack.go | 14 +++++++-- lnwire/shutdown.go | 22 +++++-------- lnwire/update_add_htlc.go | 10 ++++-- lnwire/update_fail_htlc.go | 23 +++++--------- lnwire/update_fail_malformed_htlc.go | 10 ++++-- lnwire/update_fee.go | 10 ++++-- lnwire/update_fulfill_htlc.go | 10 ++++-- 32 files changed, 278 insertions(+), 231 deletions(-) diff --git a/channeldb/channel_test.go b/channeldb/channel_test.go index 5d203889..43747372 100644 --- a/channeldb/channel_test.go +++ b/channeldb/channel_test.go @@ -607,7 +607,8 @@ func TestChannelStateTransition(t *testing.T) { { LogIndex: 2, 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( 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,22 +673,25 @@ func TestChannelStateTransition(t *testing.T) { wireSig, wireSig, }, + ExtraData: make([]byte, 0), }, LogUpdates: []LogUpdate{ { LogIndex: 1, UpdateMsg: &lnwire.UpdateAddHTLC{ - ID: 1, - Amount: lnwire.NewMSatFromSatoshis(100), - Expiry: 25, + ID: 1, + Amount: lnwire.NewMSatFromSatoshis(100), + Expiry: 25, + ExtraData: make([]byte, 0), }, }, { LogIndex: 2, UpdateMsg: &lnwire.UpdateAddHTLC{ - ID: 2, - Amount: lnwire.NewMSatFromSatoshis(200), - Expiry: 50, + ID: 2, + Amount: lnwire.NewMSatFromSatoshis(200), + Expiry: 50, + ExtraData: make([]byte, 0), }, }, }, diff --git a/channeldb/waitingproof_test.go b/channeldb/waitingproof_test.go index ed1bf050..cb5b900f 100644 --- a/channeldb/waitingproof_test.go +++ b/channeldb/waitingproof_test.go @@ -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 { diff --git a/discovery/message_store_test.go b/discovery/message_store_test.go index 7d0fa1c2..12286e39 100644 --- a/discovery/message_store_test.go +++ b/discovery/message_store_test.go @@ -64,13 +64,15 @@ func randCompressedPubKey(t *testing.T) [33]byte { func randAnnounceSignatures() *lnwire.AnnounceSignatures { return &lnwire.AnnounceSignatures{ - ShortChannelID: lnwire.NewShortChanIDFromInt(rand.Uint64()), + ShortChannelID: lnwire.NewShortChanIDFromInt(rand.Uint64()), + ExtraOpaqueData: make([]byte, 0), } } func randChannelUpdate() *lnwire.ChannelUpdate { return &lnwire.ChannelUpdate{ - ShortChannelID: lnwire.NewShortChanIDFromInt(rand.Uint64()), + ShortChannelID: lnwire.NewShortChanIDFromInt(rand.Uint64()), + ExtraOpaqueData: make([]byte, 0), } } diff --git a/htlcswitch/payment_result_test.go b/htlcswitch/payment_result_test.go index 04ff57d8..aa7cbc17 100644 --- a/htlcswitch/payment_result_test.go +++ b/htlcswitch/payment_result_test.go @@ -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{}, + ChanID: chanID, + ID: 1, + Reason: []byte{}, + ExtraData: make([]byte, 0), } fail2 := &lnwire.UpdateFailHTLC{ - ChanID: chanID, - ID: 1, - Reason: reason[:], + ChanID: chanID, + ID: 1, + Reason: reason[:], + ExtraData: make([]byte, 0), } testCases := []*networkResult{ diff --git a/lnwallet/channel_test.go b/lnwallet/channel_test.go index ead91598..27ea6ac9 100644 --- a/lnwallet/channel_test.go +++ b/lnwallet/channel_test.go @@ -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 { diff --git a/lnwire/announcement_signatures.go b/lnwire/announcement_signatures.go index 639704de..14341392 100644 --- a/lnwire/announcement_signatures.go +++ b/lnwire/announcement_signatures.go @@ -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 } diff --git a/lnwire/channel_announcement.go b/lnwire/channel_announcement.go index 46efeed8..de4b72b3 100644 --- a/lnwire/channel_announcement.go +++ b/lnwire/channel_announcement.go @@ -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 diff --git a/lnwire/channel_reestablish.go b/lnwire/channel_reestablish.go index 6fa8f8ac..bfe7c53a 100644 --- a/lnwire/channel_reestablish.go +++ b/lnwire/channel_reestablish.go @@ -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 } diff --git a/lnwire/channel_update.go b/lnwire/channel_update.go index 037f3d55..80000056 100644 --- a/lnwire/channel_update.go +++ b/lnwire/channel_update.go @@ -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 } diff --git a/lnwire/closing_signed.go b/lnwire/closing_signed.go index 91b90646..7732715b 100644 --- a/lnwire/closing_signed.go +++ b/lnwire/closing_signed.go @@ -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 } diff --git a/lnwire/commit_sig.go b/lnwire/commit_sig.go index f15a9738..8856389f 100644 --- a/lnwire/commit_sig.go +++ b/lnwire/commit_sig.go @@ -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 diff --git a/lnwire/error.go b/lnwire/error.go index 19911d1f..02c07aea 100644 --- a/lnwire/error.go +++ b/lnwire/error.go @@ -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 diff --git a/lnwire/funding_created.go b/lnwire/funding_created.go index c14321ec..437b1b6a 100644 --- a/lnwire/funding_created.go +++ b/lnwire/funding_created.go @@ -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 } diff --git a/lnwire/funding_locked.go b/lnwire/funding_locked.go index c441b0be..1eeddfb6 100644 --- a/lnwire/funding_locked.go +++ b/lnwire/funding_locked.go @@ -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 } diff --git a/lnwire/funding_signed.go b/lnwire/funding_signed.go index 620f8b37..1ef15568 100644 --- a/lnwire/funding_signed.go +++ b/lnwire/funding_signed.go @@ -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 } diff --git a/lnwire/gossip_timestamp_range.go b/lnwire/gossip_timestamp_range.go index 3c28cd05..fb62e272 100644 --- a/lnwire/gossip_timestamp_range.go +++ b/lnwire/gossip_timestamp_range.go @@ -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 } diff --git a/lnwire/init_message.go b/lnwire/init_message.go index e1ddbb01..4e33fbb6 100644 --- a/lnwire/init_message.go +++ b/lnwire/init_message.go @@ -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 } diff --git a/lnwire/lnwire_test.go b/lnwire/lnwire_test.go index ea90f3c0..0c8cf475 100644 --- a/lnwire/lnwire_test.go +++ b/lnwire/lnwire_test.go @@ -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) @@ -471,7 +473,8 @@ func TestLightningWireProtocol(t *testing.T) { } req := FundingSigned{ - ChanID: ChannelID(c), + 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) @@ -570,8 +574,9 @@ func TestLightningWireProtocol(t *testing.T) { MsgChannelAnnouncement: func(v []reflect.Value, r *rand.Rand) { var err error req := ChannelAnnouncement{ - ShortChannelID: NewShortChanIDFromInt(uint64(r.Int63())), - Features: randRawFeatureVector(r), + 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 { @@ -726,7 +733,8 @@ func TestLightningWireProtocol(t *testing.T) { MsgAnnounceSignatures: func(v []reflect.Value, r *rand.Rand) { var err error req := AnnounceSignatures{ - ShortChannelID: NewShortChanIDFromInt(uint64(r.Int63())), + 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 { diff --git a/lnwire/node_announcement.go b/lnwire/node_announcement.go index 35534352..62414d4b 100644 --- a/lnwire/node_announcement.go +++ b/lnwire/node_announcement.go @@ -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. diff --git a/lnwire/onion_error_test.go b/lnwire/onion_error_test.go index 3ec147d1..8c4c131c 100644 --- a/lnwire/onion_error_test.go +++ b/lnwire/onion_error_test.go @@ -20,11 +20,12 @@ var ( testOffset = uint16(24) sig, _ = NewSigFromSignature(testSig) testChannelUpdate = ChannelUpdate{ - Signature: sig, - ShortChannelID: NewShortChanIDFromInt(1), - Timestamp: 1, - MessageFlags: 0, - ChannelFlags: 1, + Signature: sig, + ShortChannelID: NewShortChanIDFromInt(1), + Timestamp: 1, + MessageFlags: 0, + ChannelFlags: 1, + ExtraOpaqueData: make([]byte, 0), } ) diff --git a/lnwire/query_channel_range.go b/lnwire/query_channel_range.go index 9546fcd3..3bdb30e5 100644 --- a/lnwire/query_channel_range.go +++ b/lnwire/query_channel_range.go @@ -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 diff --git a/lnwire/query_short_chan_ids.go b/lnwire/query_short_chan_ids.go index 3c2b9948..bae23d9f 100644 --- a/lnwire/query_short_chan_ids.go +++ b/lnwire/query_short_chan_ids.go @@ -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 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 } diff --git a/lnwire/reply_channel_range.go b/lnwire/reply_channel_range.go index 3ff5dd4b..5167cc5a 100644 --- a/lnwire/reply_channel_range.go +++ b/lnwire/reply_channel_range.go @@ -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 diff --git a/lnwire/reply_channel_range_test.go b/lnwire/reply_channel_range_test.go index d656db55..ff341495 100644 --- a/lnwire/reply_channel_range_test.go +++ b/lnwire/reply_channel_range_test.go @@ -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 diff --git a/lnwire/reply_short_chan_ids_end.go b/lnwire/reply_short_chan_ids_end.go index d77aa0b5..92f1e8fc 100644 --- a/lnwire/reply_short_chan_ids_end.go +++ b/lnwire/reply_short_chan_ids_end.go @@ -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 } diff --git a/lnwire/revoke_and_ack.go b/lnwire/revoke_and_ack.go index 0cfa2bc2..b187fae6 100644 --- a/lnwire/revoke_and_ack.go +++ b/lnwire/revoke_and_ack.go @@ -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 diff --git a/lnwire/shutdown.go b/lnwire/shutdown.go index 94d10a90..e27681e4 100644 --- a/lnwire/shutdown.go +++ b/lnwire/shutdown.go @@ -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 } diff --git a/lnwire/update_add_htlc.go b/lnwire/update_add_htlc.go index 028c6320..9211d39f 100644 --- a/lnwire/update_add_htlc.go +++ b/lnwire/update_add_htlc.go @@ -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 diff --git a/lnwire/update_fail_htlc.go b/lnwire/update_fail_htlc.go index 194f2ecd..09666ac2 100644 --- a/lnwire/update_fail_htlc.go +++ b/lnwire/update_fail_htlc.go @@ -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 diff --git a/lnwire/update_fail_malformed_htlc.go b/lnwire/update_fail_malformed_htlc.go index 39d4b870..b28ec29f 100644 --- a/lnwire/update_fail_malformed_htlc.go +++ b/lnwire/update_fail_malformed_htlc.go @@ -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 diff --git a/lnwire/update_fee.go b/lnwire/update_fee.go index 2d27c377..25ab180c 100644 --- a/lnwire/update_fee.go +++ b/lnwire/update_fee.go @@ -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 diff --git a/lnwire/update_fulfill_htlc.go b/lnwire/update_fulfill_htlc.go index 6c0e6339..36977b1e 100644 --- a/lnwire/update_fulfill_htlc.go +++ b/lnwire/update_fulfill_htlc.go @@ -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