From 8024fd72f8e79dab9f8d3d10e49b2953e096c702 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Mon, 20 Feb 2017 22:02:42 -0800 Subject: [PATCH] lnwire: create distinct type for UpdateFailHTLC failure reason This commit creates a distint type for the opaque failure reason within the UpdateFailHTLC message. This new type is needed as this is the only variable length byte slice within the protocol and therefore requires a length prefix in order to serialize/deserialize properly. --- lnwire/lnwire.go | 33 +++++++++++++++++++++------------ lnwire/update_fail_htlc.go | 15 ++++++++++----- lnwire/update_fail_htlc_test.go | 2 +- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/lnwire/lnwire.go b/lnwire/lnwire.go index a44c1fbb..752355e8 100644 --- a/lnwire/lnwire.go +++ b/lnwire/lnwire.go @@ -72,12 +72,6 @@ func writeElement(w io.Writer, element interface{}) error { if _, err := w.Write(b[:]); err != nil { return err } - case FailCode: - var b [2]byte - binary.BigEndian.PutUint16(b[:], uint16(e)) - if _, err := w.Write(b[:]); err != nil { - return err - } case ErrorCode: var b [2]byte binary.BigEndian.PutUint16(b[:], uint16(e)) @@ -170,6 +164,16 @@ func writeElement(w io.Writer, element interface{}) error { if _, err := w.Write(b[:]); err != nil { return err } + case OpaqueReason: + var l [2]byte + binary.BigEndian.PutUint16(l[:], uint16(len(e))) + if _, err := w.Write(l[:]); err != nil { + return err + } + + if _, err := w.Write(e[:]); err != nil { + return err + } case []byte: if _, err := w.Write(e[:]); err != nil { return err @@ -339,12 +343,6 @@ func readElement(r io.Reader, element interface{}) error { return err } *e = b[0] - case *FailCode: - var b [2]byte - if _, err := io.ReadFull(r, b[:]); err != nil { - return err - } - *e = FailCode(binary.BigEndian.Uint16(b[:])) case *uint16: var b [2]byte if _, err := io.ReadFull(r, b[:]); err != nil { @@ -458,6 +456,17 @@ func readElement(r io.Reader, element interface{}) error { } *e = wire.BitcoinNet(binary.BigEndian.Uint32(b[:])) return nil + case *OpaqueReason: + var l [2]byte + if _, err := io.ReadFull(r, l[:]); err != nil { + return err + } + reasonLen := binary.BigEndian.Uint16(l[:]) + + *e = OpaqueReason(make([]byte, reasonLen)) + if _, err := io.ReadFull(r, *e); err != nil { + return err + } case []byte: if _, err := io.ReadFull(r, e); err != nil { return err diff --git a/lnwire/update_fail_htlc.go b/lnwire/update_fail_htlc.go index c1f31a89..c8d663e5 100644 --- a/lnwire/update_fail_htlc.go +++ b/lnwire/update_fail_htlc.go @@ -71,13 +71,18 @@ func (c FailCode) String() string { } } +// OpaqueReason is an opaque encrypted byte slice that encodes the exact +// failure reason and additional some supplemental data. The contents of this +// slice can only be decrypted by the sender of the original HTLC. +type OpaqueReason []byte + // UpdateFailHTLC is sent by Alice to Bob in order to remove a previously added // HTLC. Upon receipt of an UpdateFailHTLC the HTLC should be removed from the // next commitment transaction, with the UpdateFailHTLC propagated backwards in // the route to fully undo the HTLC. type UpdateFailHTLC struct { - // ChannelPoint is the particular active channel that this UpdateFailHTLC - // is binded to. + // ChannelPoint is the particular active channel that this + // UpdateFailHTLC is binded to. ChannelPoint wire.OutPoint // ID references which HTLC on the remote node's commitment transaction @@ -88,7 +93,7 @@ type UpdateFailHTLC struct { // failed. This blob is only fully decryptable by the initiator of the // HTLC message. // TODO(roasbeef): properly format the encrypted failure reason - Reason []byte + Reason OpaqueReason } // A compile time check to ensure UpdateFailHTLC implements the lnwire.Message @@ -106,7 +111,7 @@ func (c *UpdateFailHTLC) Decode(r io.Reader, pver uint32) error { err := readElements(r, &c.ChannelPoint, &c.ID, - c.Reason[:], + &c.Reason, ) if err != nil { return err @@ -123,7 +128,7 @@ func (c *UpdateFailHTLC) Encode(w io.Writer, pver uint32) error { err := writeElements(w, c.ChannelPoint, c.ID, - c.Reason[:], + c.Reason, ) if err != nil { return err diff --git a/lnwire/update_fail_htlc_test.go b/lnwire/update_fail_htlc_test.go index 923e4e3b..dfce45b8 100644 --- a/lnwire/update_fail_htlc_test.go +++ b/lnwire/update_fail_htlc_test.go @@ -12,7 +12,7 @@ func TestUpdateFailHTLC(t *testing.T) { ChannelPoint: *outpoint1, ID: 22, } - copy(cancelMsg.Reason[:], bytes.Repeat([]byte{21}, 20)) + cancelMsg.Reason = []byte{byte(UnknownDestination)} // Next encode the UFH message into an empty bytes buffer. var b bytes.Buffer