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