hypercore_protocol/
schema.rs

1use hypercore::encoding::{CompactEncoding, EncodingError, HypercoreState, State};
2use hypercore::{
3    DataBlock, DataHash, DataSeek, DataUpgrade, Proof, RequestBlock, RequestSeek, RequestUpgrade,
4};
5
6/// Open message
7#[derive(Debug, Clone, PartialEq)]
8pub struct Open {
9    /// Channel id to open
10    pub channel: u64,
11    /// Protocol name
12    pub protocol: String,
13    /// Hypercore discovery key
14    pub discovery_key: Vec<u8>,
15    /// Capability hash
16    pub capability: Option<Vec<u8>>,
17}
18
19impl CompactEncoding<Open> for State {
20    fn preencode(&mut self, value: &Open) -> Result<usize, EncodingError> {
21        self.preencode(&value.channel)?;
22        self.preencode(&value.protocol)?;
23        self.preencode(&value.discovery_key)?;
24        if value.capability.is_some() {
25            self.add_end(1)?; // flags for future use
26            self.preencode_fixed_32()?;
27        }
28        Ok(self.end())
29    }
30
31    fn encode(&mut self, value: &Open, buffer: &mut [u8]) -> Result<usize, EncodingError> {
32        self.encode(&value.channel, buffer)?;
33        self.encode(&value.protocol, buffer)?;
34        self.encode(&value.discovery_key, buffer)?;
35        if let Some(capability) = &value.capability {
36            self.add_start(1)?; // flags for future use
37            self.encode_fixed_32(capability, buffer)?;
38        }
39        Ok(self.start())
40    }
41
42    fn decode(&mut self, buffer: &[u8]) -> Result<Open, EncodingError> {
43        let channel: u64 = self.decode(buffer)?;
44        let protocol: String = self.decode(buffer)?;
45        let discovery_key: Vec<u8> = self.decode(buffer)?;
46        let capability: Option<Vec<u8>> = if self.start() < self.end() {
47            self.add_start(1)?; // flags for future use
48            let capability: Vec<u8> = self.decode_fixed_32(buffer)?.to_vec();
49            Some(capability)
50        } else {
51            None
52        };
53        Ok(Open {
54            channel,
55            protocol,
56            discovery_key,
57            capability,
58        })
59    }
60}
61
62/// Close message
63#[derive(Debug, Clone, PartialEq)]
64pub struct Close {
65    /// Channel id to close
66    pub channel: u64,
67}
68
69impl CompactEncoding<Close> for State {
70    fn preencode(&mut self, value: &Close) -> Result<usize, EncodingError> {
71        self.preencode(&value.channel)
72    }
73
74    fn encode(&mut self, value: &Close, buffer: &mut [u8]) -> Result<usize, EncodingError> {
75        self.encode(&value.channel, buffer)
76    }
77
78    fn decode(&mut self, buffer: &[u8]) -> Result<Close, EncodingError> {
79        let channel: u64 = self.decode(buffer)?;
80        Ok(Close { channel })
81    }
82}
83
84/// Synchronize message. Type 0.
85#[derive(Debug, Clone, PartialEq)]
86pub struct Synchronize {
87    /// Fork id, set to 0 for an un-forked hypercore.
88    pub fork: u64,
89    /// Length of hypercore
90    pub length: u64,
91    /// Known length of the remote party, 0 for unknown.
92    pub remote_length: u64,
93    /// Downloading allowed
94    pub downloading: bool,
95    /// Uploading allowed
96    pub uploading: bool,
97    /// Upgrade possible
98    pub can_upgrade: bool,
99}
100
101impl CompactEncoding<Synchronize> for State {
102    fn preencode(&mut self, value: &Synchronize) -> Result<usize, EncodingError> {
103        self.add_end(1)?; // flags
104        self.preencode(&value.fork)?;
105        self.preencode(&value.length)?;
106        self.preencode(&value.remote_length)
107    }
108
109    fn encode(&mut self, value: &Synchronize, buffer: &mut [u8]) -> Result<usize, EncodingError> {
110        let mut flags: u8 = if value.can_upgrade { 1 } else { 0 };
111        flags |= if value.uploading { 2 } else { 0 };
112        flags |= if value.downloading { 4 } else { 0 };
113        self.encode(&flags, buffer)?;
114        self.encode(&value.fork, buffer)?;
115        self.encode(&value.length, buffer)?;
116        self.encode(&value.remote_length, buffer)
117    }
118
119    fn decode(&mut self, buffer: &[u8]) -> Result<Synchronize, EncodingError> {
120        let flags: u8 = self.decode(buffer)?;
121        let fork: u64 = self.decode(buffer)?;
122        let length: u64 = self.decode(buffer)?;
123        let remote_length: u64 = self.decode(buffer)?;
124        let can_upgrade = flags & 1 != 0;
125        let uploading = flags & 2 != 0;
126        let downloading = flags & 4 != 0;
127        Ok(Synchronize {
128            fork,
129            length,
130            remote_length,
131            can_upgrade,
132            uploading,
133            downloading,
134        })
135    }
136}
137
138/// Request message. Type 1.
139#[derive(Debug, Clone, PartialEq)]
140pub struct Request {
141    /// Request id, will be returned with corresponding [Data]
142    pub id: u64,
143    /// Current fork, set to 0 for un-forked hypercore
144    pub fork: u64,
145    /// Request for data
146    pub block: Option<RequestBlock>,
147    /// Request hash
148    pub hash: Option<RequestBlock>,
149    /// Request seek
150    pub seek: Option<RequestSeek>,
151    /// Request upgrade
152    pub upgrade: Option<RequestUpgrade>,
153}
154
155impl CompactEncoding<Request> for HypercoreState {
156    fn preencode(&mut self, value: &Request) -> Result<usize, EncodingError> {
157        self.add_end(1)?; // flags
158        self.0.preencode(&value.id)?;
159        self.0.preencode(&value.fork)?;
160        if let Some(block) = &value.block {
161            self.preencode(block)?;
162        }
163        if let Some(hash) = &value.hash {
164            self.preencode(hash)?;
165        }
166        if let Some(seek) = &value.seek {
167            self.preencode(seek)?;
168        }
169        if let Some(upgrade) = &value.upgrade {
170            self.preencode(upgrade)?;
171        }
172        Ok(self.end())
173    }
174
175    fn encode(&mut self, value: &Request, buffer: &mut [u8]) -> Result<usize, EncodingError> {
176        let mut flags: u8 = if value.block.is_some() { 1 } else { 0 };
177        flags |= if value.hash.is_some() { 2 } else { 0 };
178        flags |= if value.seek.is_some() { 4 } else { 0 };
179        flags |= if value.upgrade.is_some() { 8 } else { 0 };
180        self.0.encode(&flags, buffer)?;
181        self.0.encode(&value.id, buffer)?;
182        self.0.encode(&value.fork, buffer)?;
183        if let Some(block) = &value.block {
184            self.encode(block, buffer)?;
185        }
186        if let Some(hash) = &value.hash {
187            self.encode(hash, buffer)?;
188        }
189        if let Some(seek) = &value.seek {
190            self.encode(seek, buffer)?;
191        }
192        if let Some(upgrade) = &value.upgrade {
193            self.encode(upgrade, buffer)?;
194        }
195        Ok(self.start())
196    }
197
198    fn decode(&mut self, buffer: &[u8]) -> Result<Request, EncodingError> {
199        let flags: u8 = self.0.decode(buffer)?;
200        let id: u64 = self.0.decode(buffer)?;
201        let fork: u64 = self.0.decode(buffer)?;
202        let block: Option<RequestBlock> = if flags & 1 != 0 {
203            Some(self.decode(buffer)?)
204        } else {
205            None
206        };
207        let hash: Option<RequestBlock> = if flags & 2 != 0 {
208            Some(self.decode(buffer)?)
209        } else {
210            None
211        };
212        let seek: Option<RequestSeek> = if flags & 4 != 0 {
213            Some(self.decode(buffer)?)
214        } else {
215            None
216        };
217        let upgrade: Option<RequestUpgrade> = if flags & 8 != 0 {
218            Some(self.decode(buffer)?)
219        } else {
220            None
221        };
222        Ok(Request {
223            id,
224            fork,
225            block,
226            hash,
227            seek,
228            upgrade,
229        })
230    }
231}
232
233/// Cancel message for a [Request]. Type 2
234#[derive(Debug, Clone, PartialEq)]
235pub struct Cancel {
236    /// Request to cancel, see field `id` in [Request]
237    pub request: u64,
238}
239
240impl CompactEncoding<Cancel> for State {
241    fn preencode(&mut self, value: &Cancel) -> Result<usize, EncodingError> {
242        self.preencode(&value.request)
243    }
244
245    fn encode(&mut self, value: &Cancel, buffer: &mut [u8]) -> Result<usize, EncodingError> {
246        self.encode(&value.request, buffer)
247    }
248
249    fn decode(&mut self, buffer: &[u8]) -> Result<Cancel, EncodingError> {
250        let request: u64 = self.decode(buffer)?;
251        Ok(Cancel { request })
252    }
253}
254
255/// Data message responding to received [Request]. Type 3.
256#[derive(Debug, Clone, PartialEq)]
257pub struct Data {
258    /// Request this data is for, see field `id` in [Request]
259    pub request: u64,
260    /// Fork id, set to 0 for un-forked hypercore
261    pub fork: u64,
262    /// Response for block request
263    pub block: Option<DataBlock>,
264    /// Response for hash request
265    pub hash: Option<DataHash>,
266    /// Response for seek request
267    pub seek: Option<DataSeek>,
268    /// Response for upgrade request
269    pub upgrade: Option<DataUpgrade>,
270}
271
272impl CompactEncoding<Data> for HypercoreState {
273    fn preencode(&mut self, value: &Data) -> Result<usize, EncodingError> {
274        self.add_end(1)?; // flags
275        self.0.preencode(&value.request)?;
276        self.0.preencode(&value.fork)?;
277        if let Some(block) = &value.block {
278            self.preencode(block)?;
279        }
280        if let Some(hash) = &value.hash {
281            self.preencode(hash)?;
282        }
283        if let Some(seek) = &value.seek {
284            self.preencode(seek)?;
285        }
286        if let Some(upgrade) = &value.upgrade {
287            self.preencode(upgrade)?;
288        }
289        Ok(self.end())
290    }
291
292    fn encode(&mut self, value: &Data, buffer: &mut [u8]) -> Result<usize, EncodingError> {
293        let mut flags: u8 = if value.block.is_some() { 1 } else { 0 };
294        flags |= if value.hash.is_some() { 2 } else { 0 };
295        flags |= if value.seek.is_some() { 4 } else { 0 };
296        flags |= if value.upgrade.is_some() { 8 } else { 0 };
297        self.0.encode(&flags, buffer)?;
298        self.0.encode(&value.request, buffer)?;
299        self.0.encode(&value.fork, buffer)?;
300        if let Some(block) = &value.block {
301            self.encode(block, buffer)?;
302        }
303        if let Some(hash) = &value.hash {
304            self.encode(hash, buffer)?;
305        }
306        if let Some(seek) = &value.seek {
307            self.encode(seek, buffer)?;
308        }
309        if let Some(upgrade) = &value.upgrade {
310            self.encode(upgrade, buffer)?;
311        }
312        Ok(self.start())
313    }
314
315    fn decode(&mut self, buffer: &[u8]) -> Result<Data, EncodingError> {
316        let flags: u8 = self.0.decode(buffer)?;
317        let request: u64 = self.0.decode(buffer)?;
318        let fork: u64 = self.0.decode(buffer)?;
319        let block: Option<DataBlock> = if flags & 1 != 0 {
320            Some(self.decode(buffer)?)
321        } else {
322            None
323        };
324        let hash: Option<DataHash> = if flags & 2 != 0 {
325            Some(self.decode(buffer)?)
326        } else {
327            None
328        };
329        let seek: Option<DataSeek> = if flags & 4 != 0 {
330            Some(self.decode(buffer)?)
331        } else {
332            None
333        };
334        let upgrade: Option<DataUpgrade> = if flags & 8 != 0 {
335            Some(self.decode(buffer)?)
336        } else {
337            None
338        };
339        Ok(Data {
340            request,
341            fork,
342            block,
343            hash,
344            seek,
345            upgrade,
346        })
347    }
348}
349
350impl Data {
351    /// Transform Data message into a Proof emptying fields
352    pub fn into_proof(&mut self) -> Proof {
353        Proof {
354            fork: self.fork,
355            block: self.block.take(),
356            hash: self.hash.take(),
357            seek: self.seek.take(),
358            upgrade: self.upgrade.take(),
359        }
360    }
361}
362
363/// No data message. Type 4.
364#[derive(Debug, Clone, PartialEq)]
365pub struct NoData {
366    /// Request this message is for, see field `id` in [Request]
367    pub request: u64,
368}
369
370impl CompactEncoding<NoData> for State {
371    fn preencode(&mut self, value: &NoData) -> Result<usize, EncodingError> {
372        self.preencode(&value.request)
373    }
374
375    fn encode(&mut self, value: &NoData, buffer: &mut [u8]) -> Result<usize, EncodingError> {
376        self.encode(&value.request, buffer)
377    }
378
379    fn decode(&mut self, buffer: &[u8]) -> Result<NoData, EncodingError> {
380        let request: u64 = self.decode(buffer)?;
381        Ok(NoData { request })
382    }
383}
384
385/// Want message. Type 5.
386#[derive(Debug, Clone, PartialEq)]
387pub struct Want {
388    /// Start index
389    pub start: u64,
390    /// Length
391    pub length: u64,
392}
393impl CompactEncoding<Want> for State {
394    fn preencode(&mut self, value: &Want) -> Result<usize, EncodingError> {
395        self.preencode(&value.start)?;
396        self.preencode(&value.length)
397    }
398
399    fn encode(&mut self, value: &Want, buffer: &mut [u8]) -> Result<usize, EncodingError> {
400        self.encode(&value.start, buffer)?;
401        self.encode(&value.length, buffer)
402    }
403
404    fn decode(&mut self, buffer: &[u8]) -> Result<Want, EncodingError> {
405        let start: u64 = self.decode(buffer)?;
406        let length: u64 = self.decode(buffer)?;
407        Ok(Want { start, length })
408    }
409}
410
411/// Un-want message. Type 6.
412#[derive(Debug, Clone, PartialEq)]
413pub struct Unwant {
414    /// Start index
415    pub start: u64,
416    /// Length
417    pub length: u64,
418}
419impl CompactEncoding<Unwant> for State {
420    fn preencode(&mut self, value: &Unwant) -> Result<usize, EncodingError> {
421        self.preencode(&value.start)?;
422        self.preencode(&value.length)
423    }
424
425    fn encode(&mut self, value: &Unwant, buffer: &mut [u8]) -> Result<usize, EncodingError> {
426        self.encode(&value.start, buffer)?;
427        self.encode(&value.length, buffer)
428    }
429
430    fn decode(&mut self, buffer: &[u8]) -> Result<Unwant, EncodingError> {
431        let start: u64 = self.decode(buffer)?;
432        let length: u64 = self.decode(buffer)?;
433        Ok(Unwant { start, length })
434    }
435}
436
437/// Bitfield message. Type 7.
438#[derive(Debug, Clone, PartialEq)]
439pub struct Bitfield {
440    /// Start index of bitfield
441    pub start: u64,
442    /// Bitfield in 32 bit chunks beginning from `start`
443    pub bitfield: Vec<u32>,
444}
445impl CompactEncoding<Bitfield> for State {
446    fn preencode(&mut self, value: &Bitfield) -> Result<usize, EncodingError> {
447        self.preencode(&value.start)?;
448        self.preencode(&value.bitfield)
449    }
450
451    fn encode(&mut self, value: &Bitfield, buffer: &mut [u8]) -> Result<usize, EncodingError> {
452        self.encode(&value.start, buffer)?;
453        self.encode(&value.bitfield, buffer)
454    }
455
456    fn decode(&mut self, buffer: &[u8]) -> Result<Bitfield, EncodingError> {
457        let start: u64 = self.decode(buffer)?;
458        let bitfield: Vec<u32> = self.decode(buffer)?;
459        Ok(Bitfield { start, bitfield })
460    }
461}
462
463/// Range message. Type 8.
464/// Notifies Peer's that the Sender has a range of contiguous blocks.
465#[derive(Debug, Clone, PartialEq)]
466pub struct Range {
467    /// If true, notifies that data has been cleared from this range.
468    /// If false, notifies existing data range.
469    pub drop: bool,
470    /// Range starts at this index
471    pub start: u64,
472    /// Length of the range
473    pub length: u64,
474}
475
476impl CompactEncoding<Range> for State {
477    fn preencode(&mut self, value: &Range) -> Result<usize, EncodingError> {
478        self.add_end(1)?; // flags
479        self.preencode(&value.start)?;
480        if value.length != 1 {
481            self.preencode(&value.length)?;
482        }
483        Ok(self.end())
484    }
485
486    fn encode(&mut self, value: &Range, buffer: &mut [u8]) -> Result<usize, EncodingError> {
487        let mut flags: u8 = if value.drop { 1 } else { 0 };
488        flags |= if value.length == 1 { 2 } else { 0 };
489        self.encode(&flags, buffer)?;
490        self.encode(&value.start, buffer)?;
491        if value.length != 1 {
492            self.encode(&value.length, buffer)?;
493        }
494        Ok(self.end())
495    }
496
497    fn decode(&mut self, buffer: &[u8]) -> Result<Range, EncodingError> {
498        let flags: u8 = self.decode(buffer)?;
499        let start: u64 = self.decode(buffer)?;
500        let drop = flags & 1 != 0;
501        let length: u64 = if flags & 2 != 0 {
502            1
503        } else {
504            self.decode(buffer)?
505        };
506        Ok(Range {
507            drop,
508            length,
509            start,
510        })
511    }
512}
513
514/// Extension message. Type 9. Use this for custom messages in your application.
515#[derive(Debug, Clone, PartialEq)]
516pub struct Extension {
517    /// Name of the custom message
518    pub name: String,
519    /// Message content, use empty vector for no data.
520    pub message: Vec<u8>,
521}
522impl CompactEncoding<Extension> for State {
523    fn preencode(&mut self, value: &Extension) -> Result<usize, EncodingError> {
524        self.preencode(&value.name)?;
525        self.preencode_raw_buffer(&value.message)
526    }
527
528    fn encode(&mut self, value: &Extension, buffer: &mut [u8]) -> Result<usize, EncodingError> {
529        self.encode(&value.name, buffer)?;
530        self.encode_raw_buffer(&value.message, buffer)
531    }
532
533    fn decode(&mut self, buffer: &[u8]) -> Result<Extension, EncodingError> {
534        let name: String = self.decode(buffer)?;
535        let message: Vec<u8> = self.decode_raw_buffer(buffer)?;
536        Ok(Extension { name, message })
537    }
538}