lnwire: add specification onion errors

In this commit onion routing error from BOLT#4 have been added, the
initial error construction have been splitted on two parts: The first
part which contains the actual data will reside inside the lnwire
package because it contains all necessary function to decode/encode
the data. The second part obfuscation and hmac checking will resides
inside the lighting-onion package because it requires the key
generation.
This commit is contained in:
Andrey Samokhvalov
2017-06-08 20:55:41 +03:00
committed by Olaoluwa Osuntokun
parent d43a660cb1
commit 98956bc2fe
4 changed files with 1086 additions and 91 deletions

View File

@@ -1,102 +1,19 @@
package lnwire
import (
"errors"
"io"
)
// FailCode specifies the precise reason that an upstream HTLC was cancelled.
// Each UpdateFailHTLC message carries a FailCode which is to be passed back
// unaltered to the source of the HTLC within the route.
//
// TODO(roasbeef): implement proper encrypted error messages as defined in spec
// * these errors as it stands reveal the error cause to all links in the
// route and are horrible for privacy
type FailCode uint16
const (
// InsufficientCapacity indicates that a payment failed due to a link
// in the ultimate route not having enough satoshi flow to successfully
// carry the payment.
InsufficientCapacity FailCode = 0
// UpstreamTimeout indicates that an upstream link had to enforce the
// absolute HTLC timeout, removing the HTLC.
UpstreamTimeout FailCode = 1
// UnknownPaymentHash indicates that the destination did not recognize
// the payment hash.
UnknownPaymentHash FailCode = 2
// UnknownDestination indicates that the specified next hop within the
// Sphinx packet at a point in the route contained an unknown or
// invalid "next hop".
UnknownDestination FailCode = 3
// SphinxParseError indicates that an intermediate node was unable
// properly parse the HTLC.
SphinxParseError FailCode = 4
// IncorrectValue indicates that the HTLC ultimately extended to the
// destination did not match the value that was expected.
IncorrectValue FailCode = 5
// UnknownError indicates the error which should be returned, but
// not exist in specification yet.
UnknownError FailCode = 6
)
// String returns a human-readable version of the FailCode type.
func (c FailCode) String() string {
switch c {
case InsufficientCapacity:
return "InsufficientCapacity: next hop had insufficient " +
"capacity for payment"
case UpstreamTimeout:
return "UpstreamTimeout: HTLC has timed out upstream"
case UnknownPaymentHash:
return "UnknownPaymentHash: the destination did not know the " +
"preimage"
case UnknownDestination:
return "UnknownDestination: next hop unknown"
case SphinxParseError:
return "SphinxParseError: unable to parse sphinx packet"
case IncorrectValue:
return "IncorrectValue: htlc value was wrong"
default:
return "unknown reason"
}
}
import "io"
// 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
// ToFailCode converts the reason in fail code.
// TODO(andrew.shvv) Future version of this method should implement
// decryption opaque reason logic.
func (r OpaqueReason) ToFailCode() (FailCode, error) {
if len(r) != 1 {
return 0, errors.New("wrong opaque code length")
}
return FailCode(r[0]), nil
}
// 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 bound to.
// ChanIDPoint is the particular active channel that this UpdateFailHTLC
// is bound to.
ChanID ChannelID
// ID references which HTLC on the remote node's commitment transaction
@@ -106,7 +23,6 @@ type UpdateFailHTLC struct {
// Reason is an onion-encrypted blob that details why the HTLC was
// failed. This blob is only fully decryptable by the initiator of the
// HTLC message.
// TODO(roasbeef): properly format the encrypted failure reason
Reason OpaqueReason
}
@@ -151,6 +67,19 @@ func (c *UpdateFailHTLC) MsgType() MessageType {
//
// This is part of the lnwire.Message interface.
func (c *UpdateFailHTLC) MaxPayloadLength(uint32) uint32 {
// 32 + 8 + 154
return 194
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 += 166
return length
}