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.
This commit is contained in:
Olaoluwa Osuntokun 2017-02-20 22:02:42 -08:00
parent 4aa7de7f58
commit 8024fd72f8
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2
3 changed files with 32 additions and 18 deletions

@ -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

@ -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

@ -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