#[cfg_attr(not(feature = "hs-pow-full"), path = "pow/v1_stub.rs")]
pub mod v1;
use self::v1::ProofOfWorkV1;
use crate::relaycell::{extend::CircRequestExtType, extlist::Ext};
use caret::caret_int;
use tor_bytes::{EncodeResult, Reader, Result, Writer};
#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub enum ProofOfWork {
Unrecognized(UnrecognizedProofOfWork),
V1(v1::ProofOfWorkV1),
}
impl Ext for ProofOfWork {
type Id = CircRequestExtType;
fn type_id(&self) -> CircRequestExtType {
CircRequestExtType::PROOF_OF_WORK
}
fn take_body_from(b: &mut Reader<'_>) -> Result<Self> {
let scheme = b.take_u8()?;
if let Some(v1) = ProofOfWorkV1::try_take_body_from(scheme, b)? {
return Ok(ProofOfWork::V1(v1));
}
Ok(ProofOfWork::Unrecognized(
UnrecognizedProofOfWork::take_body_from(scheme, b),
))
}
fn write_body_onto<B: Writer + ?Sized>(&self, b: &mut B) -> EncodeResult<()> {
match self {
ProofOfWork::V1(v1) => v1.write_onto(b),
ProofOfWork::Unrecognized(unrecognized) => {
unrecognized.write_onto(b);
Ok(())
}
}
}
}
caret_int! {
#[non_exhaustive]
pub struct ProofOfWorkType(u8) {
V1 = 1,
}
}
#[derive(Debug, Clone, Eq, PartialEq, amplify::Getters, derive_more::Constructor)]
pub struct UnrecognizedProofOfWork {
#[getter(as_copy)]
scheme: u8,
#[getter(as_ref)]
data: Vec<u8>,
}
impl UnrecognizedProofOfWork {
pub(super) fn take_body_from(scheme: u8, b: &mut Reader<'_>) -> Self {
Self::new(scheme, b.take_rest().to_vec())
}
pub(super) fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) {
b.write_u8(self.scheme());
b.write_all(self.data());
}
}