diff --git a/lnwire/lnwire_test.go b/lnwire/lnwire_test.go index 9640d3a27..fb0b746ef 100644 --- a/lnwire/lnwire_test.go +++ b/lnwire/lnwire_test.go @@ -230,43 +230,33 @@ func TestChanUpdateChanFlags(t *testing.T) { // TestDecodeUnknownAddressType shows that an unknown address type is currently // incorrectly dealt with. func TestDecodeUnknownAddressType(t *testing.T) { - // First, we'll encode all the addresses into an intermediate - // buffer. We need to do this in order to compute the total - // length of the addresses. - addrBuf := bytes.NewBuffer(make([]byte, 0, MaxMsgBody)) - // Add a normal, clearnet address. tcpAddr := &net.TCPAddr{ IP: net.IP{127, 0, 0, 1}, Port: 8080, } - err := WriteTCPAddr(addrBuf, tcpAddr) - require.NoError(t, err) - // Add an onion address. onionAddr := &tor.OnionAddr{ OnionService: "abcdefghijklmnop.onion", Port: 9065, } - err = WriteOnionAddr(addrBuf, onionAddr) - require.NoError(t, err) - // Now add an address with an unknown type. var newAddrType addressType = math.MaxUint8 data := make([]byte, 0, 16) data = append(data, uint8(newAddrType)) - _, err = addrBuf.Write(data) - require.NoError(t, err) + opaqueAddrs := &OpaqueAddrs{ + Payload: data, + } - // Now that we have all the addresses, we can append the length. buffer := bytes.NewBuffer(make([]byte, 0, MaxMsgBody)) - err = writeDataWithLength(buffer, addrBuf.Bytes()) + err := WriteNetAddrs( + buffer, []net.Addr{tcpAddr, onionAddr, opaqueAddrs}, + ) require.NoError(t, err) - // Now we attempt to parse the bytes and we assert that we get an - // error. + // Now we attempt to parse the bytes and assert that we get an error. var addrs []net.Addr err = ReadElement(buffer, &addrs) require.Error(t, err) diff --git a/lnwire/opaque_addrs.go b/lnwire/opaque_addrs.go new file mode 100644 index 000000000..92f59ea21 --- /dev/null +++ b/lnwire/opaque_addrs.go @@ -0,0 +1,34 @@ +package lnwire + +import ( + "encoding/hex" + "net" +) + +// OpaqueAddrs is used to store the address bytes for address types that are +// unknown to us. +type OpaqueAddrs struct { + Payload []byte +} + +// A compile-time assertion to ensure that OpaqueAddrs meets the net.Addr +// interface. +var _ net.Addr = (*OpaqueAddrs)(nil) + +// String returns a human-readable string describing the target OpaqueAddrs. +// Since this is an unknown address (and could even be multiple addresses), we +// just return the hex string of the payload. +// +// This part of the net.Addr interface. +func (o *OpaqueAddrs) String() string { + return hex.EncodeToString(o.Payload) +} + +// Network returns the name of the network this address is bound to. Since this +// is an unknown address, we don't know the network and so just return a string +// indicating this. +// +// This part of the net.Addr interface. +func (o *OpaqueAddrs) Network() string { + return "unknown network for unrecognized address type" +} diff --git a/lnwire/writer.go b/lnwire/writer.go index 084e7d892..5b99ab368 100644 --- a/lnwire/writer.go +++ b/lnwire/writer.go @@ -32,6 +32,9 @@ var ( // ErrNilNetAddress is returned when a nil value is used in []net.Addr. ErrNilNetAddress = errors.New("cannot write nil address") + // ErrNilOpaqueAddrs is returned when the supplied address is nil. + ErrNilOpaqueAddrs = errors.New("cannot write nil OpaqueAddrs") + // ErrNilPublicKey is returned when a nil pubkey is used. ErrNilPublicKey = errors.New("cannot write nil pubkey") @@ -357,6 +360,16 @@ func WriteOnionAddr(buf *bytes.Buffer, addr *tor.OnionAddr) error { return WriteUint16(buf, uint16(addr.Port)) } +// WriteOpaqueAddrs appends the payload of the given OpaqueAddrs to buffer. +func WriteOpaqueAddrs(buf *bytes.Buffer, addr *OpaqueAddrs) error { + if addr == nil { + return ErrNilOpaqueAddrs + } + + _, err := buf.Write(addr.Payload) + return err +} + // WriteNetAddrs appends a slice of addresses to the provided buffer with the // length info. func WriteNetAddrs(buf *bytes.Buffer, addresses []net.Addr) error { @@ -376,6 +389,10 @@ func WriteNetAddrs(buf *bytes.Buffer, addresses []net.Addr) error { if err := WriteOnionAddr(addrBuf, a); err != nil { return err } + case *OpaqueAddrs: + if err := WriteOpaqueAddrs(addrBuf, a); err != nil { + return err + } default: return ErrNilNetAddress }