tor_cell/relaycell/hs/
pow.rs1#[cfg_attr(not(feature = "hs-pow-full"), path = "pow/v1_stub.rs")]
4pub mod v1;
5
6use self::v1::ProofOfWorkV1;
7use crate::relaycell::{extend::CircRequestExtType, extlist::Ext};
8use caret::caret_int;
9use tor_bytes::{EncodeResult, Reader, Result, Writer};
10
11#[derive(Debug, Clone, PartialEq)]
18#[non_exhaustive]
19pub enum ProofOfWork {
20 Unrecognized(UnrecognizedProofOfWork),
22 V1(v1::ProofOfWorkV1),
24}
25
26impl Ext for ProofOfWork {
27 type Id = CircRequestExtType;
28
29 fn type_id(&self) -> CircRequestExtType {
30 CircRequestExtType::PROOF_OF_WORK
31 }
32
33 fn take_body_from(b: &mut Reader<'_>) -> Result<Self> {
34 let scheme = b.take_u8()?;
35 if let Some(v1) = ProofOfWorkV1::try_take_body_from(scheme, b)? {
36 return Ok(ProofOfWork::V1(v1));
37 }
38 Ok(ProofOfWork::Unrecognized(
39 UnrecognizedProofOfWork::take_body_from(scheme, b),
40 ))
41 }
42
43 fn write_body_onto<B: Writer + ?Sized>(&self, b: &mut B) -> EncodeResult<()> {
44 match self {
45 ProofOfWork::V1(v1) => v1.write_onto(b),
46 ProofOfWork::Unrecognized(unrecognized) => {
47 unrecognized.write_onto(b);
48 Ok(())
49 }
50 }
51 }
52}
53
54caret_int! {
55 #[non_exhaustive]
57 pub struct ProofOfWorkType(u8) {
58 V1 = 1,
60 }
61}
62
63#[derive(Debug, Clone, Eq, PartialEq, amplify::Getters, derive_more::Constructor)]
70pub struct UnrecognizedProofOfWork {
71 #[getter(as_copy)]
78 scheme: u8,
79 #[getter(as_ref)]
81 data: Vec<u8>,
82}
83
84impl UnrecognizedProofOfWork {
85 pub(super) fn take_body_from(scheme: u8, b: &mut Reader<'_>) -> Self {
87 Self::new(scheme, b.take_rest().to_vec())
88 }
89
90 pub(super) fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) {
92 b.write_u8(self.scheme());
93 b.write_all(self.data());
94 }
95}