proto.rs

  1#![allow(non_snake_case)]
  2
  3use super::{entity_messages, messages, request_messages, ConnectionId, TypedEnvelope};
  4use anyhow::{anyhow, Result};
  5use async_tungstenite::tungstenite::Message as WebSocketMessage;
  6use collections::HashMap;
  7use futures::{SinkExt as _, StreamExt as _};
  8use prost::Message as _;
  9use serde::Serialize;
 10use std::any::{Any, TypeId};
 11use std::{
 12    cmp,
 13    fmt::Debug,
 14    io, iter,
 15    time::{Duration, SystemTime, UNIX_EPOCH},
 16};
 17use std::{fmt, mem};
 18
 19include!(concat!(env!("OUT_DIR"), "/zed.messages.rs"));
 20
 21pub trait EnvelopedMessage: Clone + Debug + Serialize + Sized + Send + Sync + 'static {
 22    const NAME: &'static str;
 23    const PRIORITY: MessagePriority;
 24    fn into_envelope(
 25        self,
 26        id: u32,
 27        responding_to: Option<u32>,
 28        original_sender_id: Option<PeerId>,
 29    ) -> Envelope;
 30    fn from_envelope(envelope: Envelope) -> Option<Self>;
 31}
 32
 33pub trait EntityMessage: EnvelopedMessage {
 34    type Entity;
 35    fn remote_entity_id(&self) -> u64;
 36}
 37
 38pub trait RequestMessage: EnvelopedMessage {
 39    type Response: EnvelopedMessage;
 40}
 41
 42pub trait AnyTypedEnvelope: 'static + Send + Sync {
 43    fn payload_type_id(&self) -> TypeId;
 44    fn payload_type_name(&self) -> &'static str;
 45    fn as_any(&self) -> &dyn Any;
 46    fn into_any(self: Box<Self>) -> Box<dyn Any + Send + Sync>;
 47    fn is_background(&self) -> bool;
 48    fn original_sender_id(&self) -> Option<PeerId>;
 49    fn sender_id(&self) -> ConnectionId;
 50    fn message_id(&self) -> u32;
 51}
 52
 53pub enum MessagePriority {
 54    Foreground,
 55    Background,
 56}
 57
 58impl<T: EnvelopedMessage> AnyTypedEnvelope for TypedEnvelope<T> {
 59    fn payload_type_id(&self) -> TypeId {
 60        TypeId::of::<T>()
 61    }
 62
 63    fn payload_type_name(&self) -> &'static str {
 64        T::NAME
 65    }
 66
 67    fn as_any(&self) -> &dyn Any {
 68        self
 69    }
 70
 71    fn into_any(self: Box<Self>) -> Box<dyn Any + Send + Sync> {
 72        self
 73    }
 74
 75    fn is_background(&self) -> bool {
 76        matches!(T::PRIORITY, MessagePriority::Background)
 77    }
 78
 79    fn original_sender_id(&self) -> Option<PeerId> {
 80        self.original_sender_id
 81    }
 82
 83    fn sender_id(&self) -> ConnectionId {
 84        self.sender_id
 85    }
 86
 87    fn message_id(&self) -> u32 {
 88        self.message_id
 89    }
 90}
 91
 92impl PeerId {
 93    pub fn from_u64(peer_id: u64) -> Self {
 94        let owner_id = (peer_id >> 32) as u32;
 95        let id = peer_id as u32;
 96        Self { owner_id, id }
 97    }
 98
 99    pub fn as_u64(self) -> u64 {
100        ((self.owner_id as u64) << 32) | (self.id as u64)
101    }
102}
103
104impl Copy for PeerId {}
105
106impl Eq for PeerId {}
107
108impl Ord for PeerId {
109    fn cmp(&self, other: &Self) -> cmp::Ordering {
110        self.owner_id
111            .cmp(&other.owner_id)
112            .then_with(|| self.id.cmp(&other.id))
113    }
114}
115
116impl PartialOrd for PeerId {
117    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
118        Some(self.cmp(other))
119    }
120}
121
122impl std::hash::Hash for PeerId {
123    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
124        self.owner_id.hash(state);
125        self.id.hash(state);
126    }
127}
128
129impl fmt::Display for PeerId {
130    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
131        write!(f, "{}/{}", self.owner_id, self.id)
132    }
133}
134
135messages!(
136    (Ack, Foreground),
137    (AckBufferOperation, Background),
138    (AckChannelMessage, Background),
139    (AddNotification, Foreground),
140    (AddProjectCollaborator, Foreground),
141    (ApplyCodeAction, Background),
142    (ApplyCodeActionResponse, Background),
143    (ApplyCompletionAdditionalEdits, Background),
144    (ApplyCompletionAdditionalEditsResponse, Background),
145    (BufferReloaded, Foreground),
146    (BufferSaved, Foreground),
147    (Call, Foreground),
148    (CallCanceled, Foreground),
149    (CancelCall, Foreground),
150    (ChannelMessageSent, Foreground),
151    (CopyProjectEntry, Foreground),
152    (CreateBufferForPeer, Foreground),
153    (CreateChannel, Foreground),
154    (CreateChannelResponse, Foreground),
155    (CreateProjectEntry, Foreground),
156    (CreateRoom, Foreground),
157    (CreateRoomResponse, Foreground),
158    (DeclineCall, Foreground),
159    (DeleteChannel, Foreground),
160    (DeleteNotification, Foreground),
161    (DeleteProjectEntry, Foreground),
162    (Error, Foreground),
163    (ExpandProjectEntry, Foreground),
164    (ExpandProjectEntryResponse, Foreground),
165    (Follow, Foreground),
166    (FollowResponse, Foreground),
167    (FormatBuffers, Foreground),
168    (FormatBuffersResponse, Foreground),
169    (FuzzySearchUsers, Foreground),
170    (GetChannelMembers, Foreground),
171    (GetChannelMembersResponse, Foreground),
172    (GetChannelMessages, Background),
173    (GetChannelMessagesById, Background),
174    (GetChannelMessagesResponse, Background),
175    (GetCodeActions, Background),
176    (GetCodeActionsResponse, Background),
177    (GetCompletions, Background),
178    (GetCompletionsResponse, Background),
179    (GetDefinition, Background),
180    (GetDefinitionResponse, Background),
181    (GetDocumentHighlights, Background),
182    (GetDocumentHighlightsResponse, Background),
183    (GetHover, Background),
184    (GetHoverResponse, Background),
185    (GetNotifications, Foreground),
186    (GetNotificationsResponse, Foreground),
187    (GetPrivateUserInfo, Foreground),
188    (GetPrivateUserInfoResponse, Foreground),
189    (GetProjectSymbols, Background),
190    (GetProjectSymbolsResponse, Background),
191    (GetReferences, Background),
192    (GetReferencesResponse, Background),
193    (GetTypeDefinition, Background),
194    (GetTypeDefinitionResponse, Background),
195    (GetUsers, Foreground),
196    (Hello, Foreground),
197    (IncomingCall, Foreground),
198    (InlayHints, Background),
199    (InlayHintsResponse, Background),
200    (InviteChannelMember, Foreground),
201    (JoinChannel, Foreground),
202    (JoinChannelBuffer, Foreground),
203    (JoinChannelBufferResponse, Foreground),
204    (JoinChannelChat, Foreground),
205    (JoinChannelChatResponse, Foreground),
206    (JoinProject, Foreground),
207    (JoinProjectResponse, Foreground),
208    (JoinRoom, Foreground),
209    (JoinRoomResponse, Foreground),
210    (LeaveChannelBuffer, Background),
211    (LeaveChannelChat, Foreground),
212    (LeaveProject, Foreground),
213    (LeaveRoom, Foreground),
214    (MarkNotificationRead, Foreground),
215    (MoveChannel, Foreground),
216    (OnTypeFormatting, Background),
217    (OnTypeFormattingResponse, Background),
218    (OpenBufferById, Background),
219    (OpenBufferByPath, Background),
220    (OpenBufferForSymbol, Background),
221    (OpenBufferForSymbolResponse, Background),
222    (OpenBufferResponse, Background),
223    (PerformRename, Background),
224    (PerformRenameResponse, Background),
225    (Ping, Foreground),
226    (PrepareRename, Background),
227    (PrepareRenameResponse, Background),
228    (ProjectEntryResponse, Foreground),
229    (RefreshInlayHints, Foreground),
230    (RejoinChannelBuffers, Foreground),
231    (RejoinChannelBuffersResponse, Foreground),
232    (RejoinRoom, Foreground),
233    (RejoinRoomResponse, Foreground),
234    (ReloadBuffers, Foreground),
235    (ReloadBuffersResponse, Foreground),
236    (RemoveChannelMember, Foreground),
237    (RemoveChannelMessage, Foreground),
238    (RemoveContact, Foreground),
239    (RemoveProjectCollaborator, Foreground),
240    (RenameChannel, Foreground),
241    (RenameChannelResponse, Foreground),
242    (RenameProjectEntry, Foreground),
243    (RequestContact, Foreground),
244    (ResolveCompletionDocumentation, Background),
245    (ResolveCompletionDocumentationResponse, Background),
246    (ResolveInlayHint, Background),
247    (ResolveInlayHintResponse, Background),
248    (RespondToChannelInvite, Foreground),
249    (RespondToContactRequest, Foreground),
250    (RoomUpdated, Foreground),
251    (SaveBuffer, Foreground),
252    (SetChannelMemberRole, Foreground),
253    (SetChannelVisibility, Foreground),
254    (SearchProject, Background),
255    (SearchProjectResponse, Background),
256    (SendChannelMessage, Background),
257    (SendChannelMessageResponse, Background),
258    (ShareProject, Foreground),
259    (ShareProjectResponse, Foreground),
260    (ShowContacts, Foreground),
261    (StartLanguageServer, Foreground),
262    (SynchronizeBuffers, Foreground),
263    (SynchronizeBuffersResponse, Foreground),
264    (Test, Foreground),
265    (Unfollow, Foreground),
266    (UnshareProject, Foreground),
267    (UpdateBuffer, Foreground),
268    (UpdateBufferFile, Foreground),
269    (UpdateChannelBuffer, Foreground),
270    (UpdateChannelBufferCollaborators, Foreground),
271    (UpdateChannels, Foreground),
272    (UpdateContacts, Foreground),
273    (UpdateDiagnosticSummary, Foreground),
274    (UpdateDiffBase, Foreground),
275    (UpdateFollowers, Foreground),
276    (UpdateInviteInfo, Foreground),
277    (UpdateLanguageServer, Foreground),
278    (UpdateParticipantLocation, Foreground),
279    (UpdateProject, Foreground),
280    (UpdateProjectCollaborator, Foreground),
281    (UpdateWorktree, Foreground),
282    (UpdateWorktreeSettings, Foreground),
283    (UsersResponse, Foreground),
284    (LspExtExpandMacro, Background),
285    (LspExtExpandMacroResponse, Background),
286);
287
288request_messages!(
289    (ApplyCodeAction, ApplyCodeActionResponse),
290    (
291        ApplyCompletionAdditionalEdits,
292        ApplyCompletionAdditionalEditsResponse
293    ),
294    (Call, Ack),
295    (CancelCall, Ack),
296    (CopyProjectEntry, ProjectEntryResponse),
297    (CreateChannel, CreateChannelResponse),
298    (CreateProjectEntry, ProjectEntryResponse),
299    (CreateRoom, CreateRoomResponse),
300    (DeclineCall, Ack),
301    (DeleteChannel, Ack),
302    (DeleteProjectEntry, ProjectEntryResponse),
303    (ExpandProjectEntry, ExpandProjectEntryResponse),
304    (Follow, FollowResponse),
305    (FormatBuffers, FormatBuffersResponse),
306    (FuzzySearchUsers, UsersResponse),
307    (GetChannelMembers, GetChannelMembersResponse),
308    (GetChannelMessages, GetChannelMessagesResponse),
309    (GetChannelMessagesById, GetChannelMessagesResponse),
310    (GetCodeActions, GetCodeActionsResponse),
311    (GetCompletions, GetCompletionsResponse),
312    (GetDefinition, GetDefinitionResponse),
313    (GetDocumentHighlights, GetDocumentHighlightsResponse),
314    (GetHover, GetHoverResponse),
315    (GetNotifications, GetNotificationsResponse),
316    (GetPrivateUserInfo, GetPrivateUserInfoResponse),
317    (GetProjectSymbols, GetProjectSymbolsResponse),
318    (GetReferences, GetReferencesResponse),
319    (GetTypeDefinition, GetTypeDefinitionResponse),
320    (GetUsers, UsersResponse),
321    (IncomingCall, Ack),
322    (InlayHints, InlayHintsResponse),
323    (InviteChannelMember, Ack),
324    (JoinChannel, JoinRoomResponse),
325    (JoinChannelBuffer, JoinChannelBufferResponse),
326    (JoinChannelChat, JoinChannelChatResponse),
327    (JoinProject, JoinProjectResponse),
328    (JoinRoom, JoinRoomResponse),
329    (LeaveChannelBuffer, Ack),
330    (LeaveRoom, Ack),
331    (MarkNotificationRead, Ack),
332    (MoveChannel, Ack),
333    (OnTypeFormatting, OnTypeFormattingResponse),
334    (OpenBufferById, OpenBufferResponse),
335    (OpenBufferByPath, OpenBufferResponse),
336    (OpenBufferForSymbol, OpenBufferForSymbolResponse),
337    (PerformRename, PerformRenameResponse),
338    (Ping, Ack),
339    (PrepareRename, PrepareRenameResponse),
340    (RefreshInlayHints, Ack),
341    (RejoinChannelBuffers, RejoinChannelBuffersResponse),
342    (RejoinRoom, RejoinRoomResponse),
343    (ReloadBuffers, ReloadBuffersResponse),
344    (RemoveChannelMember, Ack),
345    (RemoveChannelMessage, Ack),
346    (RemoveContact, Ack),
347    (RenameChannel, RenameChannelResponse),
348    (RenameProjectEntry, ProjectEntryResponse),
349    (RequestContact, Ack),
350    (
351        ResolveCompletionDocumentation,
352        ResolveCompletionDocumentationResponse
353    ),
354    (ResolveInlayHint, ResolveInlayHintResponse),
355    (RespondToChannelInvite, Ack),
356    (RespondToContactRequest, Ack),
357    (SaveBuffer, BufferSaved),
358    (SearchProject, SearchProjectResponse),
359    (SendChannelMessage, SendChannelMessageResponse),
360    (SetChannelMemberRole, Ack),
361    (SetChannelVisibility, Ack),
362    (ShareProject, ShareProjectResponse),
363    (SynchronizeBuffers, SynchronizeBuffersResponse),
364    (Test, Test),
365    (UpdateBuffer, Ack),
366    (UpdateParticipantLocation, Ack),
367    (UpdateProject, Ack),
368    (UpdateWorktree, Ack),
369    (LspExtExpandMacro, LspExtExpandMacroResponse),
370);
371
372entity_messages!(
373    {project_id, ShareProject},
374    AddProjectCollaborator,
375    ApplyCodeAction,
376    ApplyCompletionAdditionalEdits,
377    BufferReloaded,
378    BufferSaved,
379    CopyProjectEntry,
380    CreateBufferForPeer,
381    CreateProjectEntry,
382    DeleteProjectEntry,
383    ExpandProjectEntry,
384    FormatBuffers,
385    GetCodeActions,
386    GetCompletions,
387    GetDefinition,
388    GetDocumentHighlights,
389    GetHover,
390    GetProjectSymbols,
391    GetReferences,
392    GetTypeDefinition,
393    InlayHints,
394    JoinProject,
395    LeaveProject,
396    OnTypeFormatting,
397    OpenBufferById,
398    OpenBufferByPath,
399    OpenBufferForSymbol,
400    PerformRename,
401    PrepareRename,
402    RefreshInlayHints,
403    ReloadBuffers,
404    RemoveProjectCollaborator,
405    RenameProjectEntry,
406    ResolveCompletionDocumentation,
407    ResolveInlayHint,
408    SaveBuffer,
409    SearchProject,
410    StartLanguageServer,
411    SynchronizeBuffers,
412    UnshareProject,
413    UpdateBuffer,
414    UpdateBufferFile,
415    UpdateDiagnosticSummary,
416    UpdateDiffBase,
417    UpdateLanguageServer,
418    UpdateProject,
419    UpdateProjectCollaborator,
420    UpdateWorktree,
421    UpdateWorktreeSettings,
422    LspExtExpandMacro,
423);
424
425entity_messages!(
426    {channel_id, Channel},
427    ChannelMessageSent,
428    RemoveChannelMessage,
429    UpdateChannelBuffer,
430    UpdateChannelBufferCollaborators,
431);
432
433const KIB: usize = 1024;
434const MIB: usize = KIB * 1024;
435const MAX_BUFFER_LEN: usize = MIB;
436
437/// A stream of protobuf messages.
438pub struct MessageStream<S> {
439    stream: S,
440    encoding_buffer: Vec<u8>,
441}
442
443#[allow(clippy::large_enum_variant)]
444#[derive(Debug)]
445pub enum Message {
446    Envelope(Envelope),
447    Ping,
448    Pong,
449}
450
451impl<S> MessageStream<S> {
452    pub fn new(stream: S) -> Self {
453        Self {
454            stream,
455            encoding_buffer: Vec::new(),
456        }
457    }
458
459    pub fn inner_mut(&mut self) -> &mut S {
460        &mut self.stream
461    }
462}
463
464impl<S> MessageStream<S>
465where
466    S: futures::Sink<WebSocketMessage, Error = anyhow::Error> + Unpin,
467{
468    pub async fn write(&mut self, message: Message) -> Result<(), anyhow::Error> {
469        #[cfg(any(test, feature = "test-support"))]
470        const COMPRESSION_LEVEL: i32 = -7;
471
472        #[cfg(not(any(test, feature = "test-support")))]
473        const COMPRESSION_LEVEL: i32 = 4;
474
475        match message {
476            Message::Envelope(message) => {
477                self.encoding_buffer.reserve(message.encoded_len());
478                message
479                    .encode(&mut self.encoding_buffer)
480                    .map_err(io::Error::from)?;
481                let buffer =
482                    zstd::stream::encode_all(self.encoding_buffer.as_slice(), COMPRESSION_LEVEL)
483                        .unwrap();
484
485                self.encoding_buffer.clear();
486                self.encoding_buffer.shrink_to(MAX_BUFFER_LEN);
487                self.stream.send(WebSocketMessage::Binary(buffer)).await?;
488            }
489            Message::Ping => {
490                self.stream
491                    .send(WebSocketMessage::Ping(Default::default()))
492                    .await?;
493            }
494            Message::Pong => {
495                self.stream
496                    .send(WebSocketMessage::Pong(Default::default()))
497                    .await?;
498            }
499        }
500
501        Ok(())
502    }
503}
504
505impl<S> MessageStream<S>
506where
507    S: futures::Stream<Item = Result<WebSocketMessage, anyhow::Error>> + Unpin,
508{
509    pub async fn read(&mut self) -> Result<Message, anyhow::Error> {
510        while let Some(bytes) = self.stream.next().await {
511            match bytes? {
512                WebSocketMessage::Binary(bytes) => {
513                    zstd::stream::copy_decode(bytes.as_slice(), &mut self.encoding_buffer).unwrap();
514                    let envelope = Envelope::decode(self.encoding_buffer.as_slice())
515                        .map_err(io::Error::from)?;
516
517                    self.encoding_buffer.clear();
518                    self.encoding_buffer.shrink_to(MAX_BUFFER_LEN);
519                    return Ok(Message::Envelope(envelope));
520                }
521                WebSocketMessage::Ping(_) => return Ok(Message::Ping),
522                WebSocketMessage::Pong(_) => return Ok(Message::Pong),
523                WebSocketMessage::Close(_) => break,
524                _ => {}
525            }
526        }
527        Err(anyhow!("connection closed"))
528    }
529}
530
531impl From<Timestamp> for SystemTime {
532    fn from(val: Timestamp) -> Self {
533        UNIX_EPOCH
534            .checked_add(Duration::new(val.seconds, val.nanos))
535            .unwrap()
536    }
537}
538
539impl From<SystemTime> for Timestamp {
540    fn from(time: SystemTime) -> Self {
541        let duration = time.duration_since(UNIX_EPOCH).unwrap();
542        Self {
543            seconds: duration.as_secs(),
544            nanos: duration.subsec_nanos(),
545        }
546    }
547}
548
549impl From<u128> for Nonce {
550    fn from(nonce: u128) -> Self {
551        let upper_half = (nonce >> 64) as u64;
552        let lower_half = nonce as u64;
553        Self {
554            upper_half,
555            lower_half,
556        }
557    }
558}
559
560impl From<Nonce> for u128 {
561    fn from(nonce: Nonce) -> Self {
562        let upper_half = (nonce.upper_half as u128) << 64;
563        let lower_half = nonce.lower_half as u128;
564        upper_half | lower_half
565    }
566}
567
568pub fn split_worktree_update(
569    mut message: UpdateWorktree,
570    max_chunk_size: usize,
571) -> impl Iterator<Item = UpdateWorktree> {
572    let mut done_files = false;
573
574    let mut repository_map = message
575        .updated_repositories
576        .into_iter()
577        .map(|repo| (repo.work_directory_id, repo))
578        .collect::<HashMap<_, _>>();
579
580    iter::from_fn(move || {
581        if done_files {
582            return None;
583        }
584
585        let updated_entries_chunk_size = cmp::min(message.updated_entries.len(), max_chunk_size);
586        let updated_entries: Vec<_> = message
587            .updated_entries
588            .drain(..updated_entries_chunk_size)
589            .collect();
590
591        let removed_entries_chunk_size = cmp::min(message.removed_entries.len(), max_chunk_size);
592        let removed_entries = message
593            .removed_entries
594            .drain(..removed_entries_chunk_size)
595            .collect();
596
597        done_files = message.updated_entries.is_empty() && message.removed_entries.is_empty();
598
599        let mut updated_repositories = Vec::new();
600
601        if !repository_map.is_empty() {
602            for entry in &updated_entries {
603                if let Some(repo) = repository_map.remove(&entry.id) {
604                    updated_repositories.push(repo)
605                }
606            }
607        }
608
609        let removed_repositories = if done_files {
610            mem::take(&mut message.removed_repositories)
611        } else {
612            Default::default()
613        };
614
615        if done_files {
616            updated_repositories.extend(mem::take(&mut repository_map).into_values());
617        }
618
619        Some(UpdateWorktree {
620            project_id: message.project_id,
621            worktree_id: message.worktree_id,
622            root_name: message.root_name.clone(),
623            abs_path: message.abs_path.clone(),
624            updated_entries,
625            removed_entries,
626            scan_id: message.scan_id,
627            is_last_update: done_files && message.is_last_update,
628            updated_repositories,
629            removed_repositories,
630        })
631    })
632}
633
634#[cfg(test)]
635mod tests {
636    use super::*;
637
638    #[gpui::test]
639    async fn test_buffer_size() {
640        let (tx, rx) = futures::channel::mpsc::unbounded();
641        let mut sink = MessageStream::new(tx.sink_map_err(|_| anyhow!("")));
642        sink.write(Message::Envelope(Envelope {
643            payload: Some(envelope::Payload::UpdateWorktree(UpdateWorktree {
644                root_name: "abcdefg".repeat(10),
645                ..Default::default()
646            })),
647            ..Default::default()
648        }))
649        .await
650        .unwrap();
651        assert!(sink.encoding_buffer.capacity() <= MAX_BUFFER_LEN);
652        sink.write(Message::Envelope(Envelope {
653            payload: Some(envelope::Payload::UpdateWorktree(UpdateWorktree {
654                root_name: "abcdefg".repeat(1000000),
655                ..Default::default()
656            })),
657            ..Default::default()
658        }))
659        .await
660        .unwrap();
661        assert!(sink.encoding_buffer.capacity() <= MAX_BUFFER_LEN);
662
663        let mut stream = MessageStream::new(rx.map(anyhow::Ok));
664        stream.read().await.unwrap();
665        assert!(stream.encoding_buffer.capacity() <= MAX_BUFFER_LEN);
666        stream.read().await.unwrap();
667        assert!(stream.encoding_buffer.capacity() <= MAX_BUFFER_LEN);
668    }
669
670    #[gpui::test]
671    fn test_converting_peer_id_from_and_to_u64() {
672        let peer_id = PeerId {
673            owner_id: 10,
674            id: 3,
675        };
676        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
677        let peer_id = PeerId {
678            owner_id: u32::MAX,
679            id: 3,
680        };
681        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
682        let peer_id = PeerId {
683            owner_id: 10,
684            id: u32::MAX,
685        };
686        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
687        let peer_id = PeerId {
688            owner_id: u32::MAX,
689            id: u32::MAX,
690        };
691        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
692    }
693}