1use compact_encoding::{
2 CompactEncoding, EncodingError, map_decode, map_encode, sum_encoded_size, take_array,
3 take_array_mut, write_array, write_slice,
4};
5use hypercore_schema::{
6 DataBlock, DataHash, DataSeek, DataUpgrade, Proof, RequestBlock, RequestSeek, RequestUpgrade,
7};
8use tracing::instrument;
9
10#[derive(Debug, Clone, PartialEq)]
12pub struct Open {
13 pub channel: u64,
15 pub protocol: String,
17 pub discovery_key: Vec<u8>,
19 pub capability: Option<Vec<u8>>,
21}
22
23impl CompactEncoding for Open {
24 #[instrument(skip_all, ret, err)]
25 fn encoded_size(&self) -> Result<usize, EncodingError> {
26 let out = sum_encoded_size!(self.channel, self.protocol, self.discovery_key);
27 if self.capability.is_some() {
28 return Ok(
29 out
30 + 1 + 32, );
33 }
34 Ok(out)
35 }
36
37 #[instrument(skip_all)]
38 fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
39 let rest = map_encode!(buffer, self.channel, self.protocol, self.discovery_key);
40 if let Some(cap) = &self.capability {
41 let (_, rest) = take_array_mut::<1>(rest)?;
42 return write_slice(cap, rest);
43 }
44 Ok(rest)
45 }
46
47 #[instrument(skip_all, err)]
48 fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
49 where
50 Self: Sized,
51 {
52 let ((channel, protocol, discovery_key), rest) =
53 map_decode!(buffer, [u64, String, Vec<u8>]);
54 let (capability, rest) = if !rest.is_empty() {
57 let (_, rest) = take_array::<1>(rest)?;
58 let (capability, rest) = take_array::<32>(rest)?;
59 (Some(capability.to_vec()), rest)
60 } else {
61 (None, rest)
62 };
63 Ok((
64 Self {
65 channel,
66 protocol,
67 discovery_key,
68 capability,
69 },
70 rest,
71 ))
72 }
73}
74
75#[derive(Debug, Clone, PartialEq)]
77pub struct Close {
78 pub channel: u64,
80}
81
82impl CompactEncoding for Close {
83 fn encoded_size(&self) -> Result<usize, EncodingError> {
84 self.channel.encoded_size()
85 }
86
87 fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
88 self.channel.encode(buffer)
89 }
90
91 fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
92 where
93 Self: Sized,
94 {
95 let (channel, rest) = u64::decode(buffer)?;
96 Ok((Self { channel }, rest))
97 }
98}
99
100#[derive(Debug, Clone, PartialEq)]
102pub struct Synchronize {
103 pub fork: u64,
105 pub length: u64,
107 pub remote_length: u64,
109 pub downloading: bool,
111 pub uploading: bool,
113 pub can_upgrade: bool,
115}
116
117impl CompactEncoding for Synchronize {
118 fn encoded_size(&self) -> Result<usize, EncodingError> {
119 Ok(1 + sum_encoded_size!(self.fork, self.length, self.remote_length))
120 }
121
122 fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
123 let mut flags: u8 = if self.can_upgrade { 1 } else { 0 };
124 flags |= if self.uploading { 2 } else { 0 };
125 flags |= if self.downloading { 4 } else { 0 };
126 let rest = write_array(&[flags], buffer)?;
127 Ok(map_encode!(
128 rest,
129 self.fork,
130 self.length,
131 self.remote_length
132 ))
133 }
134
135 fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
136 where
137 Self: Sized,
138 {
139 let ([flags], rest) = take_array::<1>(buffer)?;
140 let ((fork, length, remote_length), rest) = map_decode!(rest, [u64, u64, u64]);
141 let can_upgrade = flags & 1 != 0;
142 let uploading = flags & 2 != 0;
143 let downloading = flags & 4 != 0;
144 Ok((
145 Synchronize {
146 fork,
147 length,
148 remote_length,
149 can_upgrade,
150 uploading,
151 downloading,
152 },
153 rest,
154 ))
155 }
156}
157
158#[derive(Debug, Clone, PartialEq)]
160pub struct Request {
161 pub id: u64,
163 pub fork: u64,
165 pub block: Option<RequestBlock>,
167 pub hash: Option<RequestBlock>,
169 pub seek: Option<RequestSeek>,
171 pub upgrade: Option<RequestUpgrade>,
173 pub manifest: bool,
176 pub priority: u64,
180}
181
182macro_rules! maybe_decode {
183 ($cond:expr, $type:ty, $buf:ident) => {
184 if $cond {
185 let (result, rest) = <$type>::decode($buf)?;
186 (Some(result), rest)
187 } else {
188 (None, $buf)
189 }
190 };
191}
192
193impl CompactEncoding for Request {
194 fn encoded_size(&self) -> Result<usize, EncodingError> {
195 let mut out = 1; out += sum_encoded_size!(self.id, self.fork);
197 if let Some(block) = &self.block {
198 out += block.encoded_size()?;
199 }
200 if let Some(hash) = &self.hash {
201 out += hash.encoded_size()?;
202 }
203 if let Some(seek) = &self.seek {
204 out += seek.encoded_size()?;
205 }
206 if let Some(upgrade) = &self.upgrade {
207 out += upgrade.encoded_size()?;
208 }
209 if self.priority != 0 {
210 out += self.priority.encoded_size()?;
211 }
212 Ok(out)
213 }
214
215 fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
216 let mut flags: u8 = if self.block.is_some() { 1 } else { 0 };
217 flags |= if self.hash.is_some() { 2 } else { 0 };
218 flags |= if self.seek.is_some() { 4 } else { 0 };
219 flags |= if self.upgrade.is_some() { 8 } else { 0 };
220 flags |= if self.manifest { 16 } else { 0 };
221 flags |= if self.priority != 0 { 32 } else { 0 };
222 let mut rest = write_array(&[flags], buffer)?;
223 rest = map_encode!(rest, self.id, self.fork);
224
225 if let Some(block) = &self.block {
226 rest = block.encode(rest)?;
227 }
228 if let Some(hash) = &self.hash {
229 rest = hash.encode(rest)?;
230 }
231 if let Some(seek) = &self.seek {
232 rest = seek.encode(rest)?;
233 }
234 if let Some(upgrade) = &self.upgrade {
235 rest = upgrade.encode(rest)?;
236 }
237
238 if self.priority != 0 {
239 rest = self.priority.encode(rest)?;
240 }
241
242 Ok(rest)
243 }
244
245 fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
246 where
247 Self: Sized,
248 {
249 let ([flags], rest) = take_array::<1>(buffer)?;
250 let ((id, fork), rest) = map_decode!(rest, [u64, u64]);
251
252 let (block, rest) = maybe_decode!(flags & 1 != 0, RequestBlock, rest);
253 let (hash, rest) = maybe_decode!(flags & 2 != 0, RequestBlock, rest);
254 let (seek, rest) = maybe_decode!(flags & 4 != 0, RequestSeek, rest);
255 let (upgrade, rest) = maybe_decode!(flags & 8 != 0, RequestUpgrade, rest);
256 let manifest = flags & 16 != 0;
257 let (priority, rest) = if flags & 32 != 0 {
258 u64::decode(rest)?
259 } else {
260 (0, rest)
261 };
262 Ok((
263 Request {
264 id,
265 fork,
266 block,
267 hash,
268 seek,
269 upgrade,
270 manifest,
271 priority,
272 },
273 rest,
274 ))
275 }
276}
277
278#[derive(Debug, Clone, PartialEq)]
280pub struct Cancel {
281 pub request: u64,
283}
284
285impl CompactEncoding for Cancel {
286 fn encoded_size(&self) -> Result<usize, EncodingError> {
287 self.request.encoded_size()
288 }
289
290 fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
291 self.request.encode(buffer)
292 }
293
294 fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
295 where
296 Self: Sized,
297 {
298 let (request, rest) = u64::decode(buffer)?;
299 Ok((Cancel { request }, rest))
300 }
301}
302
303#[derive(Debug, Clone, PartialEq)]
305pub struct Data {
306 pub request: u64,
308 pub fork: u64,
310 pub block: Option<DataBlock>,
312 pub hash: Option<DataHash>,
314 pub seek: Option<DataSeek>,
316 pub upgrade: Option<DataUpgrade>,
318}
319
320macro_rules! opt_encoded_size {
321 ($opt:expr, $sum:ident) => {
322 if let Some(thing) = $opt {
323 $sum += thing.encoded_size()?;
324 }
325 };
326}
327
328macro_rules! opt_encoded_bytes {
333 ($opt:expr, $buf:ident) => {
334 if let Some(thing) = $opt {
335 thing.encode($buf)?
336 } else {
337 $buf
338 }
339 };
340}
341impl CompactEncoding for Data {
342 fn encoded_size(&self) -> Result<usize, EncodingError> {
343 let mut out = 1; out += sum_encoded_size!(self.request, self.fork);
345 opt_encoded_size!(&self.block, out);
346 opt_encoded_size!(&self.hash, out);
347 opt_encoded_size!(&self.seek, out);
348 opt_encoded_size!(&self.upgrade, out);
349 Ok(out)
350 }
351
352 fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
353 let mut flags: u8 = if self.block.is_some() { 1 } else { 0 };
354 flags |= if self.hash.is_some() { 2 } else { 0 };
355 flags |= if self.seek.is_some() { 4 } else { 0 };
356 flags |= if self.upgrade.is_some() { 8 } else { 0 };
357 let rest = write_array(&[flags], buffer)?;
358 let rest = map_encode!(rest, self.request, self.fork);
359
360 let rest = opt_encoded_bytes!(&self.block, rest);
361 let rest = opt_encoded_bytes!(&self.hash, rest);
362 let rest = opt_encoded_bytes!(&self.seek, rest);
363 let rest = opt_encoded_bytes!(&self.upgrade, rest);
364 Ok(rest)
365 }
366
367 fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
368 where
369 Self: Sized,
370 {
371 let ([flags], rest) = take_array::<1>(buffer)?;
372 let ((request, fork), rest) = map_decode!(rest, [u64, u64]);
373 let (block, rest) = maybe_decode!(flags & 1 != 0, DataBlock, rest);
374 let (hash, rest) = maybe_decode!(flags & 2 != 0, DataHash, rest);
375 let (seek, rest) = maybe_decode!(flags & 4 != 0, DataSeek, rest);
376 let (upgrade, rest) = maybe_decode!(flags & 8 != 0, DataUpgrade, rest);
377 Ok((
378 Data {
379 request,
380 fork,
381 block,
382 hash,
383 seek,
384 upgrade,
385 },
386 rest,
387 ))
388 }
389}
390
391impl Data {
392 pub fn into_proof(self) -> Proof {
394 Proof {
395 fork: self.fork,
396 block: self.block,
397 hash: self.hash,
398 seek: self.seek,
399 upgrade: self.upgrade,
400 }
401 }
402}
403
404#[derive(Debug, Clone, PartialEq)]
406pub struct NoData {
407 pub request: u64,
409}
410
411impl CompactEncoding for NoData {
412 fn encoded_size(&self) -> Result<usize, EncodingError> {
413 Ok(sum_encoded_size!(self.request))
414 }
415
416 fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
417 Ok(map_encode!(buffer, self.request))
418 }
419
420 fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
421 where
422 Self: Sized,
423 {
424 let (request, rest) = u64::decode(buffer)?;
425 Ok((Self { request }, rest))
426 }
427}
428
429#[derive(Debug, Clone, PartialEq)]
431pub struct Want {
432 pub start: u64,
434 pub length: u64,
436}
437
438impl CompactEncoding for Want {
439 fn encoded_size(&self) -> Result<usize, EncodingError> {
440 Ok(sum_encoded_size!(self.start, self.length))
441 }
442
443 fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
444 Ok(map_encode!(buffer, self.start, self.length))
445 }
446
447 fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
448 where
449 Self: Sized,
450 {
451 let ((start, length), rest) = map_decode!(buffer, [u64, u64]);
452 Ok((Self { start, length }, rest))
453 }
454}
455
456#[derive(Debug, Clone, PartialEq)]
458pub struct Unwant {
459 pub start: u64,
461 pub length: u64,
463}
464
465impl CompactEncoding for Unwant {
466 fn encoded_size(&self) -> Result<usize, EncodingError> {
467 Ok(sum_encoded_size!(self.start, self.length))
468 }
469
470 fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
471 Ok(map_encode!(buffer, self.start, self.length))
472 }
473
474 fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
475 where
476 Self: Sized,
477 {
478 let ((start, length), rest) = map_decode!(buffer, [u64, u64]);
479 Ok((Self { start, length }, rest))
480 }
481}
482
483#[derive(Debug, Clone, PartialEq)]
485pub struct Bitfield {
486 pub start: u64,
488 pub bitfield: Vec<u32>,
490}
491impl CompactEncoding for Bitfield {
492 fn encoded_size(&self) -> Result<usize, EncodingError> {
493 Ok(sum_encoded_size!(self.start, self.bitfield))
494 }
495
496 fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
497 Ok(map_encode!(buffer, self.start, self.bitfield))
498 }
499
500 fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
501 where
502 Self: Sized,
503 {
504 let ((start, bitfield), rest) = map_decode!(buffer, [u64, Vec<u32>]);
505 Ok((Self { start, bitfield }, rest))
506 }
507}
508
509#[derive(Debug, Clone, PartialEq)]
512pub struct Range {
513 pub drop: bool,
516 pub start: u64,
518 pub length: u64,
520}
521
522impl CompactEncoding for Range {
523 fn encoded_size(&self) -> Result<usize, EncodingError> {
524 let mut out = 1 + sum_encoded_size!(self.start);
525 if self.length != 1 {
526 out += self.length.encoded_size()?;
527 }
528 Ok(out)
529 }
530
531 fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
532 let mut flags: u8 = if self.drop { 1 } else { 0 };
533 flags |= if self.length == 1 { 2 } else { 0 };
534 let rest = write_array(&[flags], buffer)?;
535 let rest = self.start.encode(rest)?;
536 if self.length != 1 {
537 return self.length.encode(rest);
538 }
539 Ok(rest)
540 }
541
542 fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
543 where
544 Self: Sized,
545 {
546 let ([flags], rest) = take_array::<1>(buffer)?;
547 let (start, rest) = u64::decode(rest)?;
548 let drop = flags & 1 != 0;
549 let (length, rest) = if flags & 2 != 0 {
550 (1, rest)
551 } else {
552 u64::decode(rest)?
553 };
554 Ok((
555 Range {
556 drop,
557 length,
558 start,
559 },
560 rest,
561 ))
562 }
563}
564
565#[derive(Debug, Clone, PartialEq)]
567pub struct Extension {
568 pub name: String,
570 pub message: Vec<u8>,
572}
573impl CompactEncoding for Extension {
574 fn encoded_size(&self) -> Result<usize, EncodingError> {
575 Ok(sum_encoded_size!(self.name, self.message))
576 }
577
578 fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
579 Ok(map_encode!(buffer, self.name, self.message))
580 }
581
582 fn decode(buffer: &[u8]) -> Result<(Self, &[u8]), EncodingError>
583 where
584 Self: Sized,
585 {
586 let ((name, message), rest) = map_decode!(buffer, [String, Vec<u8>]);
587 Ok((Self { name, message }, rest))
588 }
589}