@@ -39,12 +39,27 @@ const maxUnderlaysPerPeer = 20
3939const maxUnderlayBytes = 2048
4040
4141// SerializeUnderlays serializes a slice of multiaddrs into a single byte slice.
42+ // If the slice contains exactly one address, the standard, backward-compatible
43+ // multiaddr format is used. For zero or more than one address, a custom list format
44+ // prefixed with a magic byte is utilized.
45+ // Returns an error wrapping ErrUnderlayCountExceeded or ErrUnderlayByteSizeExceeded
46+ // if the limits are violated.
4247func SerializeUnderlays (addrs []multiaddr.Multiaddr ) ([]byte , error ) {
4348 if len (addrs ) > maxUnderlaysPerPeer {
4449 return nil , fmt .Errorf ("underlay count %d exceeds maximum of %d: %w" , len (addrs ), maxUnderlaysPerPeer , ErrUnderlayCountExceeded )
4550 }
4651
47- // The format is: [prefix_byte][varint_len_1][addr_1_bytes][varint_len_2][addr_2_bytes]...
52+ // Backward compatibility if exactly one address is present.
53+ if len (addrs ) == 1 {
54+ b := addrs [0 ].Bytes ()
55+ if len (b ) > maxUnderlayBytes {
56+ return nil , fmt .Errorf ("underlay data size %d exceeds maximum of %d bytes: %w" , len (b ), maxUnderlayBytes , ErrUnderlayByteSizeExceeded )
57+ }
58+ return b , nil
59+ }
60+
61+ // For 0 or 2+ addresses, the custom list format with the prefix is used.
62+ // The format is: [prefix_byte][varint_len_1][addr_1_bytes]...
4863 var buf bytes.Buffer
4964 buf .WriteByte (underlayListPrefix )
5065
@@ -62,6 +77,8 @@ func SerializeUnderlays(addrs []multiaddr.Multiaddr) ([]byte, error) {
6277}
6378
6479// DeserializeUnderlays deserializes a byte slice into a slice of multiaddrs.
80+ // The data format is automatically detected as either a single legacy multiaddr
81+ // or a list of multiaddrs (identified by underlayListPrefix), and is parsed accordingly.
6582func DeserializeUnderlays (data []byte ) ([]multiaddr.Multiaddr , error ) {
6683 if len (data ) == 0 {
6784 return nil , errors .New ("cannot deserialize empty byte slice" )
@@ -71,14 +88,22 @@ func DeserializeUnderlays(data []byte) ([]multiaddr.Multiaddr, error) {
7188 return nil , fmt .Errorf ("underlay data size %d exceeds maximum of %d bytes: %w" , len (data ), maxUnderlayBytes , ErrUnderlayByteSizeExceeded )
7289 }
7390
74- if data [0 ] != underlayListPrefix {
75- return nil , errors .New ("invalid underlay payload: missing list prefix" )
91+ // If the data begins with the magic prefix, it is handled as a list.
92+ if data [0 ] == underlayListPrefix {
93+ return deserializeList (data [1 :])
7694 }
7795
78- return deserializeList (data [1 :])
96+ // Otherwise, the data is handled as a single, backward-compatible multiaddr.
97+ addr , err := multiaddr .NewMultiaddrBytes (data )
98+ if err != nil {
99+ return nil , fmt .Errorf ("failed to parse as single multiaddr: %w" , err )
100+ }
101+ // The result is returned as a single-element slice for a consistent return type.
102+ return []multiaddr.Multiaddr {addr }, nil
79103}
80104
81- // deserializeList handles the parsing of the underlays list format.
105+ // deserializeList handles the parsing of the custom list format.
106+ // The provided data is expected to have already been stripped of the underlayListPrefix.
82107func deserializeList (data []byte ) ([]multiaddr.Multiaddr , error ) {
83108 var addrs []multiaddr.Multiaddr
84109 r := bytes .NewReader (data )
0 commit comments