lnwire/onion_error: add InvalidOnionPayload failure
This commit is contained in:
parent
3c91c3a8ff
commit
0fc506e044
@ -11,6 +11,7 @@ import (
|
|||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
"github.com/go-errors/errors"
|
"github.com/go-errors/errors"
|
||||||
|
"github.com/lightningnetwork/lnd/tlv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FailureMessage represents the onion failure object identified by its unique
|
// FailureMessage represents the onion failure object identified by its unique
|
||||||
@ -78,6 +79,7 @@ const (
|
|||||||
CodeFinalIncorrectCltvExpiry FailCode = 18
|
CodeFinalIncorrectCltvExpiry FailCode = 18
|
||||||
CodeFinalIncorrectHtlcAmount FailCode = 19
|
CodeFinalIncorrectHtlcAmount FailCode = 19
|
||||||
CodeExpiryTooFar FailCode = 21
|
CodeExpiryTooFar FailCode = 21
|
||||||
|
CodeInvalidOnionPayload = FlagPerm | 22
|
||||||
)
|
)
|
||||||
|
|
||||||
// String returns the string representation of the failure code.
|
// String returns the string representation of the failure code.
|
||||||
@ -149,6 +151,9 @@ func (c FailCode) String() string {
|
|||||||
case CodeExpiryTooFar:
|
case CodeExpiryTooFar:
|
||||||
return "ExpiryTooFar"
|
return "ExpiryTooFar"
|
||||||
|
|
||||||
|
case CodeInvalidOnionPayload:
|
||||||
|
return "InvalidOnionPayload"
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return "<unknown>"
|
return "<unknown>"
|
||||||
}
|
}
|
||||||
@ -1117,6 +1122,66 @@ func (f *FailExpiryTooFar) Error() string {
|
|||||||
return f.Code().String()
|
return f.Code().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InvalidOnionPayload is returned if the hop could not process the TLV payload
|
||||||
|
// enclosed in the onion.
|
||||||
|
type InvalidOnionPayload struct {
|
||||||
|
// Type is the TLV type that caused the specific failure.
|
||||||
|
Type uint64
|
||||||
|
|
||||||
|
// Offset is the byte offset within the payload where the failure
|
||||||
|
// occurred.
|
||||||
|
Offset uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInvalidOnionPayload initializes a new InvalidOnionPayload failure.
|
||||||
|
func NewInvalidOnionPayload(typ uint64, offset uint16) *InvalidOnionPayload {
|
||||||
|
return &InvalidOnionPayload{
|
||||||
|
Type: typ,
|
||||||
|
Offset: offset,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code returns the failure unique code.
|
||||||
|
//
|
||||||
|
// NOTE: Part of the FailureMessage interface.
|
||||||
|
func (f *InvalidOnionPayload) Code() FailCode {
|
||||||
|
return CodeInvalidOnionPayload
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a human readable string describing the target FailureMessage.
|
||||||
|
//
|
||||||
|
// NOTE: Implements the error interface.
|
||||||
|
func (f *InvalidOnionPayload) Error() string {
|
||||||
|
return fmt.Sprintf("%v(type=%v, offset=%d)",
|
||||||
|
f.Code(), f.Type, f.Offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode decodes the failure from bytes stream.
|
||||||
|
//
|
||||||
|
// NOTE: Part of the Serializable interface.
|
||||||
|
func (f *InvalidOnionPayload) Decode(r io.Reader, pver uint32) error {
|
||||||
|
var buf [8]byte
|
||||||
|
typ, err := tlv.ReadVarInt(r, &buf)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
f.Type = typ
|
||||||
|
|
||||||
|
return ReadElements(r, &f.Offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode writes the failure in bytes stream.
|
||||||
|
//
|
||||||
|
// NOTE: Part of the Serializable interface.
|
||||||
|
func (f *InvalidOnionPayload) Encode(w io.Writer, pver uint32) error {
|
||||||
|
var buf [8]byte
|
||||||
|
if err := tlv.WriteVarInt(w, f.Type, &buf); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return WriteElements(w, f.Offset)
|
||||||
|
}
|
||||||
|
|
||||||
// DecodeFailure decodes, validates, and parses the lnwire onion failure, for
|
// DecodeFailure decodes, validates, and parses the lnwire onion failure, for
|
||||||
// the provided protocol version.
|
// the provided protocol version.
|
||||||
func DecodeFailure(r io.Reader, pver uint32) (FailureMessage, error) {
|
func DecodeFailure(r io.Reader, pver uint32) (FailureMessage, error) {
|
||||||
@ -1298,6 +1363,9 @@ func makeEmptyOnionError(code FailCode) (FailureMessage, error) {
|
|||||||
case CodeExpiryTooFar:
|
case CodeExpiryTooFar:
|
||||||
return &FailExpiryTooFar{}, nil
|
return &FailExpiryTooFar{}, nil
|
||||||
|
|
||||||
|
case CodeInvalidOnionPayload:
|
||||||
|
return &InvalidOnionPayload{}, nil
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, errors.Errorf("unknown error code: %v", code)
|
return nil, errors.Errorf("unknown error code: %v", code)
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,8 @@ var (
|
|||||||
testAmount = MilliSatoshi(1)
|
testAmount = MilliSatoshi(1)
|
||||||
testCtlvExpiry = uint32(2)
|
testCtlvExpiry = uint32(2)
|
||||||
testFlags = uint16(2)
|
testFlags = uint16(2)
|
||||||
|
testType = uint64(3)
|
||||||
|
testOffset = uint16(24)
|
||||||
sig, _ = NewSigFromSignature(testSig)
|
sig, _ = NewSigFromSignature(testSig)
|
||||||
testChannelUpdate = ChannelUpdate{
|
testChannelUpdate = ChannelUpdate{
|
||||||
Signature: sig,
|
Signature: sig,
|
||||||
@ -50,6 +52,7 @@ var onionFailures = []FailureMessage{
|
|||||||
NewChannelDisabled(testFlags, testChannelUpdate),
|
NewChannelDisabled(testFlags, testChannelUpdate),
|
||||||
NewFinalIncorrectCltvExpiry(testCtlvExpiry),
|
NewFinalIncorrectCltvExpiry(testCtlvExpiry),
|
||||||
NewFinalIncorrectHtlcAmount(testAmount),
|
NewFinalIncorrectHtlcAmount(testAmount),
|
||||||
|
NewInvalidOnionPayload(testType, testOffset),
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestEncodeDecodeCode tests the ability of onion errors to be properly encoded
|
// TestEncodeDecodeCode tests the ability of onion errors to be properly encoded
|
||||||
|
Loading…
Reference in New Issue
Block a user