lnwire: ensure we're able to decode legacy FailUnknownPaymentHash
In this commit, we modify the decoding of the FailUnknownPaymentHash message to ensure we're able to fully decode the legacy serialization of the onion error. We do this by catching the `io.EOF` error as it's returned when _no_ bytes are read. If this is the case, then only the error type was serialized and not also the optional amount.
This commit is contained in:
parent
5167b02312
commit
17fd5eef07
@ -366,7 +366,20 @@ func (f FailUnknownPaymentHash) Error() string {
|
||||
//
|
||||
// NOTE: Part of the Serializable interface.
|
||||
func (f *FailUnknownPaymentHash) Decode(r io.Reader, pver uint32) error {
|
||||
return ReadElement(r, &f.amount)
|
||||
err := ReadElement(r, &f.amount)
|
||||
switch {
|
||||
// This is an optional tack on that was added later in the protocol. As
|
||||
// a result, older nodes may not include this value. We'll account for
|
||||
// this by checking for io.EOF here which means that no bytes were read
|
||||
// at all.
|
||||
case err == io.EOF:
|
||||
return nil
|
||||
|
||||
case err != nil:
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Encode writes the failure in bytes stream.
|
||||
|
@ -33,10 +33,10 @@ var onionFailures = []FailureMessage{
|
||||
&FailPermanentChannelFailure{},
|
||||
&FailRequiredChannelFeatureMissing{},
|
||||
&FailUnknownNextPeer{},
|
||||
&FailUnknownPaymentHash{},
|
||||
&FailIncorrectPaymentAmount{},
|
||||
&FailFinalExpiryTooSoon{},
|
||||
|
||||
NewFailUnknownPaymentHash(99),
|
||||
NewInvalidOnionVersion(testOnionHash),
|
||||
NewInvalidOnionHmac(testOnionHash),
|
||||
NewInvalidOnionKey(testOnionHash),
|
||||
@ -167,3 +167,30 @@ func TestWriteOnionErrorChanUpdate(t *testing.T) {
|
||||
trueUpdateLength, encodedLen)
|
||||
}
|
||||
}
|
||||
|
||||
// TestFailUnknownPaymentHashOptionalAmount tests that we're able to decode an
|
||||
// UnknownPaymentHash error that doesn't have the optional amount. This ensures
|
||||
// we're able to decode FailUnknownPaymentHash messages from older nodes.
|
||||
func TestFailUnknownPaymentHashOptionalAmount(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Creation an error that is a non-pointer will allow us to skip the
|
||||
// type assertion for the Serializable interface. As a result, the
|
||||
// amount body won't be written.
|
||||
onionError := FailUnknownPaymentHash{}
|
||||
|
||||
var b bytes.Buffer
|
||||
if err := EncodeFailure(&b, onionError, 0); err != nil {
|
||||
t.Fatalf("unable to encode failure: %v", err)
|
||||
}
|
||||
|
||||
onionError2, err := DecodeFailure(bytes.NewReader(b.Bytes()), 0)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to decode error: %v", err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(onionError, onionError) {
|
||||
t.Fatalf("expected %v, got %v", spew.Sdump(onionError),
|
||||
spew.Sdump(onionError2))
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user