mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-07-28 13:52:55 +02:00
lnwire: explicitly handle empty list when encoding short chan IDs
Before this commit, both writing and reading an encoded empty set of short channel IDs from the wire would fail. Prior to this commit, we treated decoding an empty set as a caller error, and failed to write out the zlib encoding of an empty set in a way that us and the other implementations were able to read. To fix this, rather than giving zlib an empty buffer to write out (which results in an encoding with the zlib header data and the rest), we just write a blank slice. When decoding, if we have an empty query body, then we'll return a `nil` slice. With the above changes, we'll now always write out an empty short channel ID set as: ``` 0001 (1 byte follows) || <encoding_type> ``` A new test has also been added to exercise this case for both known encoding types.
This commit is contained in:
committed by
Olaoluwa Osuntokun
parent
83ff6a59d4
commit
17200afc57
@@ -2,7 +2,11 @@ package lnwire
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
)
|
||||
|
||||
// TestReplyChannelRangeUnsorted tests that decoding a ReplyChannelRange request
|
||||
@@ -32,3 +36,72 @@ func TestReplyChannelRangeUnsorted(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestReplyChannelRangeEmpty tests encoding and decoding a ReplyChannelRange
|
||||
// that doesn't contain any channel results.
|
||||
func TestReplyChannelRangeEmpty(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
emptyChannelsTests := []struct {
|
||||
name string
|
||||
encType ShortChanIDEncoding
|
||||
encodedHex string
|
||||
}{
|
||||
{
|
||||
name: "empty plain encoding",
|
||||
encType: EncodingSortedPlain,
|
||||
encodedHex: "000000000000000000000000000000000000000" +
|
||||
"00000000000000000000000000000000100000002" +
|
||||
"01000100",
|
||||
},
|
||||
{
|
||||
name: "empty zlib encoding",
|
||||
encType: EncodingSortedZlib,
|
||||
encodedHex: "00000000000000000000000000000000000000" +
|
||||
"0000000000000000000000000000000001000000" +
|
||||
"0201000101",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range emptyChannelsTests {
|
||||
test := test
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
req := ReplyChannelRange{
|
||||
QueryChannelRange: QueryChannelRange{
|
||||
FirstBlockHeight: 1,
|
||||
NumBlocks: 2,
|
||||
},
|
||||
Complete: 1,
|
||||
EncodingType: test.encType,
|
||||
ShortChanIDs: nil,
|
||||
}
|
||||
|
||||
// First decode the hex string in the test case into a
|
||||
// new ReplyChannelRange message. It should be
|
||||
// identical to the one created above.
|
||||
var req2 ReplyChannelRange
|
||||
b, _ := hex.DecodeString(test.encodedHex)
|
||||
err := req2.Decode(bytes.NewReader(b), 0)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to decode req: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(req, req2) {
|
||||
t.Fatalf("requests don't match: expected %v got %v",
|
||||
spew.Sdump(req), spew.Sdump(req2))
|
||||
}
|
||||
|
||||
// Next, we go in the reverse direction: encode the
|
||||
// request created above, and assert that it matches
|
||||
// the raw byte encoding.
|
||||
var b2 bytes.Buffer
|
||||
err = req.Encode(&b2, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to encode req: %v", err)
|
||||
}
|
||||
if !bytes.Equal(b, b2.Bytes()) {
|
||||
t.Fatalf("encoded requests don't match: expected %x got %x",
|
||||
b, b2.Bytes())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user