aranya_runtime/sync/
mod.rs

1//! Interface for syncing state between clients.
2
3use aranya_buggy::Bug;
4use postcard::Error as PostcardError;
5use serde::{Deserialize, Serialize};
6
7use crate::{
8    command::{Command, CommandId, Priority},
9    storage::{StorageError, MAX_COMMAND_LENGTH},
10    Address, Prior,
11};
12
13mod requester;
14mod responder;
15
16pub use requester::SyncRequester;
17pub use responder::{PeerCache, SyncResponder};
18
19// TODO: These should all be compile time parameters
20
21/// The maximum number of heads that will be stored for a peer.
22pub const PEER_HEAD_MAX: usize = 10;
23
24/// The maximum number of samples in a request
25const COMMAND_SAMPLE_MAX: usize = 100;
26
27/// The maximum number of missing segments that can be requested
28/// in a single message
29const REQUEST_MISSING_MAX: usize = 100;
30
31/// The maximum number of commands in a response
32pub const COMMAND_RESPONSE_MAX: usize = 100;
33
34/// The maximum number of segments which can be stored to send
35const SEGMENT_BUFFER_MAX: usize = 100;
36
37/// The maximum size of a sync message
38// TODO: Use postcard to calculate max size (which accounts for overhead)
39// https://docs.rs/postcard/latest/postcard/experimental/max_size/index.html
40pub const MAX_SYNC_MESSAGE_SIZE: usize = 1024 + MAX_COMMAND_LENGTH * COMMAND_RESPONSE_MAX;
41
42/// Represents high-level data of a command.
43#[derive(Serialize, Deserialize, Debug)]
44pub struct CommandMeta {
45    id: CommandId,
46    priority: Priority,
47    parent: Prior<Address>,
48    policy_length: u32,
49    length: u32,
50    max_cut: usize,
51}
52
53/// An error returned by the syncer.
54#[derive(Debug, thiserror::Error)]
55pub enum SyncError {
56    #[error("sync session ID does not match")]
57    SessionMismatch,
58    #[error("missing sync response")]
59    MissingSyncResponse,
60    #[error("syncer state not valid for this message")]
61    SessionState,
62    #[error("syncer not ready for operation")]
63    NotReady,
64    #[error("too many commands sent")]
65    CommandOverflow,
66    #[error("storage error: {0}")]
67    Storage(#[from] StorageError),
68    #[error("serialize error: {0}")]
69    Serialize(#[from] PostcardError),
70    #[error(transparent)]
71    Bug(#[from] Bug),
72}
73
74/// Sync command to be committed to graph.
75#[derive(Serialize, Deserialize, Debug)]
76pub struct SyncCommand<'a> {
77    priority: Priority,
78    id: CommandId,
79    parent: Prior<Address>,
80    policy: Option<&'a [u8]>,
81    data: &'a [u8],
82    max_cut: usize,
83}
84
85impl<'a> Command for SyncCommand<'a> {
86    fn priority(&self) -> Priority {
87        self.priority.clone()
88    }
89
90    fn id(&self) -> CommandId {
91        self.id
92    }
93
94    fn parent(&self) -> Prior<Address> {
95        self.parent
96    }
97
98    fn policy(&self) -> Option<&'a [u8]> {
99        self.policy
100    }
101
102    fn bytes(&self) -> &'a [u8] {
103        self.data
104    }
105
106    fn max_cut(&self) -> Result<usize, Bug> {
107        Ok(self.max_cut)
108    }
109}